最近我使用Borland C++ 5.2在遗留环境中遇到了编译器错误.我有一个.cpp文件,其中包含一些我无法控制的C源头.头部包含一个包含const成员的结构定义,并且编译器抱怨"没有构造函数的类中的常量成员".经过调查,此错误似乎与编译器有关.以下是来自各种编译器的一些示例代码:
#include <stdio.h>
typedef struct {
const float a;
} _floater;
int main()
{
_floater f = {5.1F};
printf("%f\r\n",f.a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
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 ***
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Microsoft 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
请注意,Borland在结构声明时失败,因为它有一个const成员但没有构造函数,而VS 2003没有声明,但是当你尝试用初始化列表实例化它时会抱怨 - 考虑结构是非聚合类型.VS2008和g ++非常高兴.[道歉..我刚刚意识到错误中的行#s是错误的,因为我在发布前删除了一些注释掉的行.]
Microsoft对聚合的定义如下: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.
所以,我想有两个问题:
谢谢!
标准很清楚.拥有const成员不会禁止某个类成为聚合.
8.5.1 [dcl.init.aggr]
的骨料是没有用户声明的构造的阵列或一个类(第9节)(12.1),无私有或保护非静态数据成员(第11),没有基类(第10节),并且没有虚拟功能(10.3 ).
它是合法的复制intialize一个const对象,这是一个集合初始化执行对总的成员初始化.在12.6.2 const的mem-initializer-list中没有命名没有用户声明的构造函数的对象的限制仅适用于不适用的构造函数的初始化,因为聚合初始化发生了.
至于为什么旧的编译器失败,我不知道.我只能说他们在这方面不符合标准.