C函数声明与实现中的Const
Const in C function declaration and implementation
我有一个函数在 code.h
中声明并在 code.c
中实现。
它是这样的:
void someFunc(const char*);
和
#include "code.h"
void someFunc(const char* str){ printf("%s\n", str); }
现在我发现我可以删除任何 一个 文件中的 const
(将它留在另一个文件中)并且它编译并运行没有错误.
我想知道这是什么意思?
文件之一是唯一重要的文件吗?
这听起来可能只是一种不重要的小众行为,但这一事实意味着错过 const
可能会被忽视。
What happens if declaration and definition of a function don't agree on whether an argument is const
or not?
你应该得到一个编译错误。
What to do?
更新你的编译器。
对于 gcc 4.2.1,如果我从头文件或源文件中删除 const
,我会收到一个错误消息:
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c code.c
code.c:3:6: error: conflicting types for 'someFunc'
void someFunc(const char* str){ printf("%s\n", str); }
^
./code.h:1:6: note: previous declaration is here
void someFunc(char*);
^
1 error generated.
使用 gcc 版本 4.9.2 (Debian 4.9.2-10),我得到了相同的行为。
与 gcc 的 7.1.0 版本相同的行为,在 Wandbox:
在线
我的猜测是您遇到的行为取决于 architecture/compiler 的版本。
在 C 中,如果函数声明和函数定义都对编译器可见并且不匹配,则需要进行诊断。
如果您的编译器实际上是 C++ 编译器,则声明和定义不需要匹配 - 因为它们将被视为重载。但是,如果两个重载均未定义,则会出现链接器错误(编译单元调用它们看到声明的重载,并且由于未定义该函数而链接失败)。
如果传递的参数正确,其他编译单元可以看到头文件中的声明但不能看到定义,否则将编译,否则将失败。在 C 和 C++ 中。
如果您的代码始终如一地构建和运行,那么您的编译器就没有以标准的方式运行(例如,编译选项使其在这方面不符合要求)。或者构建过程存在一些问题(例如,如果头文件或源文件依赖于更改,则对象不会被重建 - 这意味着可执行文件对应于源的旧版本)。
我有一个函数在 code.h
中声明并在 code.c
中实现。
它是这样的:
void someFunc(const char*);
和
#include "code.h"
void someFunc(const char* str){ printf("%s\n", str); }
现在我发现我可以删除任何 一个 文件中的 const
(将它留在另一个文件中)并且它编译并运行没有错误.
我想知道这是什么意思?
文件之一是唯一重要的文件吗?
这听起来可能只是一种不重要的小众行为,但这一事实意味着错过 const
可能会被忽视。
What happens if declaration and definition of a function don't agree on whether an argument is
const
or not?
你应该得到一个编译错误。
What to do?
更新你的编译器。
对于 gcc 4.2.1,如果我从头文件或源文件中删除 const
,我会收到一个错误消息:
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c code.c
code.c:3:6: error: conflicting types for 'someFunc'
void someFunc(const char* str){ printf("%s\n", str); }
^
./code.h:1:6: note: previous declaration is here
void someFunc(char*);
^
1 error generated.
使用 gcc 版本 4.9.2 (Debian 4.9.2-10),我得到了相同的行为。
与 gcc 的 7.1.0 版本相同的行为,在 Wandbox:
我的猜测是您遇到的行为取决于 architecture/compiler 的版本。
在 C 中,如果函数声明和函数定义都对编译器可见并且不匹配,则需要进行诊断。
如果您的编译器实际上是 C++ 编译器,则声明和定义不需要匹配 - 因为它们将被视为重载。但是,如果两个重载均未定义,则会出现链接器错误(编译单元调用它们看到声明的重载,并且由于未定义该函数而链接失败)。
如果传递的参数正确,其他编译单元可以看到头文件中的声明但不能看到定义,否则将编译,否则将失败。在 C 和 C++ 中。
如果您的代码始终如一地构建和运行,那么您的编译器就没有以标准的方式运行(例如,编译选项使其在这方面不符合要求)。或者构建过程存在一些问题(例如,如果头文件或源文件依赖于更改,则对象不会被重建 - 这意味着可执行文件对应于源的旧版本)。