为什么我没有 "undefined reference to"?
Why don't I have "undefined reference to"?
我在我的(大)项目中遇到了 similar problem。
//# include <string.h> // not included
void foo(char * str, const char * delim)
{
char * tok = strtok(str, delim);
// warning ^ "assignement makes pointer from integer without a cast"
// [...]
}
答案(只需添加 #include <string.h>
即可获得 strtok
的原型)确实解决了问题。
然而,由于我的知识匮乏 compiler/linker,我无法理解进程如何接受一个没有原型的函数。
我宁愿期待错误 undefined reference to function 'strtok'
,当您忘记包含正确的 header.
时,这是典型的错误
[编辑] 我明白为什么这个问题被标记为重复,但我确实认为它是不同的:我知道 "good practice" 关于包含,我只是想知道编译器的行为。但是我承认我可以在这个post中找到(部分)我的问题的答案:Are prototypes required for all functions in C89, C90 or C99? or this one: Must declare function prototype in C?
虽然链接您的二进制文件,但除非明确提及,否则您的二进制文件与默认的 C 标准库(例如 glibc
)链接,其中函数是已定义.
因此,当您错过包含 声明 的头文件时,您会得到 警告 (如果函数原型有不匹配注意) 但在链接期间,由于默认 C 库的存在,程序已成功链接 anyway.
FWIW,根据 C11
,对隐式函数声明的支持已被删除,但大多数编译器支持 不良 行为以保持遗留代码的向后兼容性。
注意:
隐式函数声明: 早些时候(在 C99,AFAIK 之前),标准没有强制要求函数具有前向声明。如果一个函数在没有前向声明的情况下被使用,它被假定为 return int
并接受任意数量的传入参数。
因为 gcc 会自动 link将您的代码与 C 库一起使用。 "undefined reference to function" 错误通常由 linker 无法解析符号时发出,并且仅当无法在任何文件中找到该符号时才会发生库的 linked(linking 的顺序可能也很重要)。但默认情况下,C 库是 link 编辑的——就好像您使用 -lc
编辑它一样 link。所以,你不会得到那个错误。
如果您告诉 gcc 不要 link 使用 -nostdlib
的 C 库,那么您将看到您预期的错误:
$ gcc -nostdlib file.c
另一方面,您应该始终为函数提供原型。
您可能对其他类似的 link 选项感兴趣,例如 -nodefaultlibs
、nostartfiles
等,您可以在 gcc's manual.
中找到它们
我在我的(大)项目中遇到了 similar problem。
//# include <string.h> // not included
void foo(char * str, const char * delim)
{
char * tok = strtok(str, delim);
// warning ^ "assignement makes pointer from integer without a cast"
// [...]
}
答案(只需添加 #include <string.h>
即可获得 strtok
的原型)确实解决了问题。
然而,由于我的知识匮乏 compiler/linker,我无法理解进程如何接受一个没有原型的函数。
我宁愿期待错误 undefined reference to function 'strtok'
,当您忘记包含正确的 header.
[编辑] 我明白为什么这个问题被标记为重复,但我确实认为它是不同的:我知道 "good practice" 关于包含,我只是想知道编译器的行为。但是我承认我可以在这个post中找到(部分)我的问题的答案:Are prototypes required for all functions in C89, C90 or C99? or this one: Must declare function prototype in C?
虽然链接您的二进制文件,但除非明确提及,否则您的二进制文件与默认的 C 标准库(例如 glibc
)链接,其中函数是已定义.
因此,当您错过包含 声明 的头文件时,您会得到 警告 (如果函数原型有不匹配注意) 但在链接期间,由于默认 C 库的存在,程序已成功链接 anyway.
FWIW,根据 C11
,对隐式函数声明的支持已被删除,但大多数编译器支持 不良 行为以保持遗留代码的向后兼容性。
注意:
隐式函数声明: 早些时候(在 C99,AFAIK 之前),标准没有强制要求函数具有前向声明。如果一个函数在没有前向声明的情况下被使用,它被假定为 return int
并接受任意数量的传入参数。
因为 gcc 会自动 link将您的代码与 C 库一起使用。 "undefined reference to function" 错误通常由 linker 无法解析符号时发出,并且仅当无法在任何文件中找到该符号时才会发生库的 linked(linking 的顺序可能也很重要)。但默认情况下,C 库是 link 编辑的——就好像您使用 -lc
编辑它一样 link。所以,你不会得到那个错误。
如果您告诉 gcc 不要 link 使用 -nostdlib
的 C 库,那么您将看到您预期的错误:
$ gcc -nostdlib file.c
另一方面,您应该始终为函数提供原型。
您可能对其他类似的 link 选项感兴趣,例如 -nodefaultlibs
、nostartfiles
等,您可以在 gcc's manual.