gpt4 book ai didi

c++ - 在 C/C++ 中初始化结构的 const 成员...取决于编译器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:05:45 25 4
gpt4 key购买 nike

最近我在使用 Borland C++ 5.2 的遗留环境中遇到编译器错误。我有一个 .cpp 文件,其中包含来自某些我无法控制的 C 源代码的 header 。 header 包含一个包含 const 成员的结构定义,编译器提示“类中没有构造函数的常量成员”。经调查,此错误似乎与编译器相关。下面是一些带有各种编译器结果的示例代码:

#include <stdio.h>

typedef struct {
const float a;
} _floater;

int main()
{
_floater f = {5.1F};

printf("%f\r\n",f.a);

return 0;
}

Borland 5.2

E:\Projects\Scratchpad>bcc32 -P const_float.c
Borland C++ 5.2 for Win32 Copyright (c) 1993, 1997 Borland International
const_float.c:
Error const_float.c 13: Constant member ' ::a' in class without constructors
*** 1 errors in Compile ***

Microsoft VS 2003.NET:

E:\Projects\Scratchpad>cl /TP const_float.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

const_float.c
const_float.c(19) : error C2552: 'f' : non-aggregates cannot be initialized with
initializer list

微软 VS 2008:

C:\Projects\Scratchpad>cl /TP const_float.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

const_float.c
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

/out:const_float.exe
const_float.obj

C:\Projects\Scratchpad>const_float.exe
5.100000

G++ 3.3.3

$ g++ const_float.c -o const_float.exe
const_float.c:25:2: warning: no newline at end of file

$ ./const_float.exe
5.100000

请注意,Borland 在声明结构时失败,因为它有一个 const 成员但没有构造函数,而 VS 2003 没有声明,但是当您尝试使用初始化列表实例化它时会提示 - 考虑结构非聚合类型。 VS2008 和 g++ 非常开心。[抱歉..我刚刚意识到错误中的 #s 行是错误的,因为我在发布前删除了一些注释掉的行。]

微软对聚合的定义在这里:http://msdn.microsoft.com/en-us/library/0s6730bb.aspx . const 成员会使结构成为非聚合结构,这对我来说并不明显,但也许他们在 2003 年就做到了。

最新的 Borland (Embarcadero) 编译器似乎也将此视为警告而不是错误:http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/wrnmembnocons_xml.html .

所以,我猜有 2 个问题:

  1. 为什么编译器存在差异?标准在这一点上是否含糊不清?
  2. 有什么解决方法吗?鉴于我被编译器版本和头文件困住了,我没有看到任何东西。

谢谢!

最佳答案

标准很明确。拥有 const 成员并不妨碍类成为聚合。

8.5.1 [dcl.init.aggr]

An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

copy-intialize const 对象是合法的,这是聚合初始化对聚合成员执行的初始化。在 12.6.2 的 mem-initializer-list 中不命名没有用户声明的构造函数的 const 对象的限制仅适用于由不应用是因为聚合初始化发生了。

至于为什么旧的编译器会失败,我不知道。我只能说他们在这方面不符合标准。

关于c++ - 在 C/C++ 中初始化结构的 const 成员...取决于编译器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6703288/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com