Visual C++ 编译器自动假定带 .C 扩展名的文件是 C 文件而不是 C++ 文件,并且拒绝 C++ 语法和关键字(c语言只能在大括号最前面申明变量)
2017-07-28 21:56
267 查看
今天在编译OpenGL红宝书附带源码中的light.c文件时遇到一个诡异的问题:
如图light .c,在不做任何修改的情况编译OK。然而只要在某些地方写了可执行代码,则会无法通过编译器编译!
(这几行代码如果写在main函数里的第一句则OK)
我用的VS08.我把该文件发给其他朋友(用的VS10),同样也是这样的问题。
然而,我把文件名改成light.cpp后,问题解决了。
现在的问题是,代码文件按的后缀背后,会如何影响编辑器的编译呢?
可以做一个简单的测试:
[cpp] view plain copy
int main()
{
#ifdef __cplusplus
printf("已定义__cpluslus");
#else
printf("未定义__cpluslus");
#endif
return 0;
}
测试结果就是:如果编译的是cpp文件,则编译器会自动帮你加入__cplusplus宏,并使用C++的编译规则。这一点MSDN其实已经明确说明:
赋予文件 .c 扩展名,例如 mysource.c。
Visual C++ 编译器自动假定带 .C 扩展名的文件是 C 文件而不是 C++ 文件,并且拒绝 C++ 语法和关键字(如 public、private 和 class)。
C++ 文件使用 .cpp 扩展名。
再来个非主流的测试。如果编译的既不是.c文件,也不是.cpp文件呢?
笔者把文件扩展名改为light.DD,结果是显示了已定义__cplusplus.也就是说vs默认除了.c文件外,统统认为是c++文件来编译。
奇怪的是,MSDN上是这样描述的:
文件扩展名决定处理文件的方式。扩展名为 .c、.cxx 或 .cpp 的 C 和 C++ 文件将被编译。其他文件(包括 .obj 文件、库 (.lib) 和模块定义 (.def) 文件)将传递给链接器而不经过处理。
现在回到最初的问题。
light.c为什么偏偏在加上了执行代码(哪怕是空代码)也会无法通过编译呢?如果是因为编译器的问题,为什么不加那几行“魔鬼代码”之前是编译ok的呢?
这仅仅是编译器的bug吗?
已经明白了。。
c语言只能在大括号最前面申明变量。。。
坑爹啊。。
http://blog.csdn.net/lsldd/article/details/6890943
如图light .c,在不做任何修改的情况编译OK。然而只要在某些地方写了可执行代码,则会无法通过编译器编译!
(这几行代码如果写在main函数里的第一句则OK)
我用的VS08.我把该文件发给其他朋友(用的VS10),同样也是这样的问题。
然而,我把文件名改成light.cpp后,问题解决了。
现在的问题是,代码文件按的后缀背后,会如何影响编辑器的编译呢?
可以做一个简单的测试:
[cpp] view plain copy
int main()
{
#ifdef __cplusplus
printf("已定义__cpluslus");
#else
printf("未定义__cpluslus");
#endif
return 0;
}
测试结果就是:如果编译的是cpp文件,则编译器会自动帮你加入__cplusplus宏,并使用C++的编译规则。这一点MSDN其实已经明确说明:
赋予文件 .c 扩展名,例如 mysource.c。
Visual C++ 编译器自动假定带 .C 扩展名的文件是 C 文件而不是 C++ 文件,并且拒绝 C++ 语法和关键字(如 public、private 和 class)。
C++ 文件使用 .cpp 扩展名。
再来个非主流的测试。如果编译的既不是.c文件,也不是.cpp文件呢?
笔者把文件扩展名改为light.DD,结果是显示了已定义__cplusplus.也就是说vs默认除了.c文件外,统统认为是c++文件来编译。
奇怪的是,MSDN上是这样描述的:
文件扩展名决定处理文件的方式。扩展名为 .c、.cxx 或 .cpp 的 C 和 C++ 文件将被编译。其他文件(包括 .obj 文件、库 (.lib) 和模块定义 (.def) 文件)将传递给链接器而不经过处理。
现在回到最初的问题。
light.c为什么偏偏在加上了执行代码(哪怕是空代码)也会无法通过编译呢?如果是因为编译器的问题,为什么不加那几行“魔鬼代码”之前是编译ok的呢?
这仅仅是编译器的bug吗?
已经明白了。。
c语言只能在大括号最前面申明变量。。。
坑爹啊。。
http://blog.csdn.net/lsldd/article/details/6890943
相关文章推荐
- Effective C++ Item 6 若不想使用编译器自动生成的函数,就该明确拒绝
- Effective C++ 条款6 若不想使用编译器自动生成的函数,就该明确拒绝
- 【教程】如何知道C/C++的标准库中有多少个函数?(说的不是常用的函数,也不是在本地磁盘中查文件头哈,并且还要有每一种函数的使用详解)
- 不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针
- Effective C++——》条款6:若不想使用编译器自动生成函数,就该明确拒绝 .
- Effective C++ Item 6 若不想使用编译器自动生成的函数,就该明确拒绝
- C++中直接拒绝编译器自动生成copy constructor和copy operator=操作(6)---《Effective C++》
- Effective C++学习笔记 条款06:如不想使用编译器自动生成的函数,就该明确拒绝
- C++如何拒绝编译器自动生成的函数
- 刨根问底:C++中未初始化全局变量为什么都会被编译器自动置0
- effect C++ 若不想使用编译器自动生成的函数,就该拒绝
- 数据文件自动扩展只能到32G?
- <Effective C++>:Item 6 :明确拒绝不想编译器自动生成的函数
- Effective C++ 条款06 若不想使用编译器自动生成的函数,就该明确拒绝
- C语言多文件编译时,编译器不检测其声明的变量类型与定义时的类型是否匹配
- 读书笔记_Effective_C++_条款六:若不想使用编译器自动生成的函数,就该明确拒绝
- 编译器错误信息: ASPNET: 请确保此代码文件中定义的类与“inherits”属性匹配,并且该类扩展的基类(例如 Page 或 UserControl)是正确的。
- 编译器错误消息: ASPNET: 请确保此代码文件中定义的类与“inherits”属性匹配,并且该类扩展的基类(例如 Page 或 UserControl)是正确的。
- 让UltraEdit自动对pro*c代码文件语法着色为c语言格式
- C++中有关volatile关键字的作用--阻止编译器将其变量优化缓存到寄存器(和线程相关)(转自百度)