为啥文件扩展名对编译有影响?
Posted
技术标签:
【中文标题】为啥文件扩展名对编译有影响?【英文标题】:Why does the filename extension make a difference to compiling?为什么文件扩展名对编译有影响? 【发布时间】:2021-02-27 06:15:09 【问题描述】:我在 CentOs8 下使用 GNU 编译器编译这段代码:
#include <stdlib.h>
int main()
int *a = malloc(3 * sizeof(int));
return 0;
当我将它命名为 a.cpp 时,两个编译命令都失败了:
g++ -o a a.cpp
gcc -o a a.cpp
但是我把它重命名为a.c之后,这个编译命令就成功了:
gcc -o a a.c
这是 C 代码,不是 C++ 代码。我相信使用gcc
或g++
应该会有所不同,但编译器似乎只考虑文件扩展名。
您能否提供一些关于此的详细信息?
【问题讨论】:
在 C++ 中,您必须转换malloc
的结果,因为 C++ 不允许与 void *
进行隐式转换。试试int* a = (int*) malloc(3*sizeof(int));
另外,<stdlib.h>
是一个 C 头文件。在 C++ 中,它是 <cstdlib>
。
@mediocrevegetable1 malloc()
根本不应该在 C++ 中使用,而是使用 new
。
@RemyLebeau 我知道这一点,但 OP 已明确声明“这是 C 代码,而不是 C++ 代码。”所以我认为这主要是 C 代码,也可能在一些 C++ 文件中使用。
@mediocrevegetable1 -- C++ 中允许隐式转换到 void*
。
【参考方案1】:
C++ 将在从 malloc()
返回的 void*
到 int*
的隐式转换上出错。而 C 允许从 void*
隐式转换为其他指针类型。
大多数编译器将默认查看文件扩展名来确定要编译到的语言。
man gcc
表明所有.c
文件默认编译为C
。而所有 .cc
、.cp
、.cxx
、.cpp
、.CPP
、.c++
和 .C
(大写 C)文件都编译为 C++
。
您可以通过 gcc/g++ 的 -x
选项覆盖此行为强制语言。
例子:
gcc -x c++ foo.c -c // compiles foo.c as C++ instead of C
gcc 和 g++ 在大多数 unix 系统上通常是相同的二进制文件。它只是根据自己的argv[0]
参数默认为不同的行为。
显式使用 g++ 和 gcc 与 -x
选项之间可能存在其他行为差异。我不确定。
【讨论】:
g++
为标准库添加额外的链接器标志,gcc
即使编译 cpp 文件也不会
gcc
使用编译器扩展来确定文件是 C 还是 C++(或其他)。可以使用 -std=c99
覆盖该关联。
@Eljay - 什么是“编译器扩展”?
*.cpp
or *.cxx
or *.cc
or *.C
假定为 C++; *.c
假定为 C; *.m
假定为 Objective-C,*.mm
假定为 Objective-C++; *.s
假定为程序集。 (这不是一个详尽的列表。)GCC 编译器(以及其他编译器)使用文件名的扩展名作为源语言的元数据线索,除非该语言提供给工具链驱动程序 (gcc
或g++
是显式调用预处理器、编译器、链接器等的工具链驱动程序。
@Eljay - 我想你没抓住我的意思。我认为您的意思是说 file 扩展名,而不是 compiler 扩展名。 ;)以上是关于为啥文件扩展名对编译有影响?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 UIView 的扩展对除了放置在 IB 上的 UIView 之外的其他控件没有直接影响?
为啥 rails 对咖啡脚本文件使用 .js.coffee 扩展名,因为它们无论如何都不能包含 JavaScript 代码?