提问人:Scott Prive 提问时间:8/14/2022 更新时间:8/14/2022 访问量:45
没有来自拆分源的输出,但在省略包含的文件时也没有警告
No output from split up source, but no warnings either, when omitting an included file
问:
我在调用 gcc 时遇到了一个问题,如果我省略库文件,我就没有从二进制文件中得到任何输出(意外的行为更改),但由于这是一个缺少的依赖项,我有点期望编译会失败(或至少警告).......c
此问题的示例来自 Head First C 第 185 页(但不是勘误表,请参阅下面的编译错误步骤):
encrypt.h:
void encrypt(char *message);
encrypt.c:
#include "encrypt.h"
void encrypt(char *message)
{
// char c; errata
while (*message) {
*message = *message ^ 31;
message++;
}
}
message_hider.c:
#include <stdio.h>
#include "encrypt.h"
int main() {
char msg[80];
while (fgets(msg, 80, stdin)) {
encrypt(msg);
printf("%s", msg);
}
}
现在,如果我按照练习说明忠实地编译,一切正常:
gcc message_hider.c encrypt.c -o message_hider
...但是运气不好,我只编译了主要的.c文件,如下所示:
$ gcc message_hider.c -o message_hider
- 这出人意料地成功构建,即使我添加了.
-Wall -Wextra -Wshadow -g
- 同样令人惊讶的是,它静默地失败了,encrypt() 函数没有输出:
$ ./message_hider < ./encrypt.h
$
我的GCC是:
$ /usr/bin/gcc --version
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
请注意,即使使用 Makefile,由于配方中的错误,我“仍然”可能最终丢失 .c 文件。
问:如果我忘记告诉文件,是否可以强制执行硬错误?gcc
.c
答:
正如我在(拼写错误的)评论中指出的那样:
系统库中可能有一个函数。
encrypt()
在 Mac 上,显示:man -s 3 encrypt
CRYPT(3) BSD 库函数手册 CRYPT(3)
NAME
crypt, encrypt, setkey -- DES 加密概要
#include <unistd.h> char * crypt(const char *key, const char *salt); void encrypt(char *block, int edflag); #include <stdlib.h> void setkey(const char *key);
...
encrypt(
) 和 setkey()
函数是 POSIX 的一部分,因此它们在大多数类似 POSIX 的系统上都可用。奇怪的是,如手册页摘录中所示,这些函数是在单独的标头中声明的 — <unistd.h> for 和 <stdlib.h>
for 。 断开连接可能有一个很好的(足够)的历史原因。
encrypt()
setkey()
您应该已经收到有关函数未声明的编译器警告 - 如果您没有,您可能正在使用 C90 标准进行编译。这是很古老的,不应该继续被教导;你需要学习 C11 或 C18(几乎相同)。
从 C99 开始,C 标准要求函数在使用前声明——您可以在不预先声明函数的情况下定义函数,但所有其他函数(除了 )都应该在使用或定义之前声明。您可以使用 GCC 编译器警告选项(如 (以及 和 ))来触发警告。其中,由 启用(且没有 )。请注意:正如评论中所指出的,不支持真正的 GCC(不是 Apple 的伪装)确实支持它。static
main()
-Wmissing-prototypes -Wstrict-prototypes
-Wold-style-declaration
-Wold-style-definition
-Wold-style-declaration
-Wextra
-Wall
clang
-Wold-style-declaration
clang
gcc
评论
unknown warning option '-Wold-style-declaration'; did you mean '-Wout-of-line-declaration'? [-Wunknown-warning-option]
-std=C18
-Wold-style-declaration
-Wold-style-declaration
encrypt()
/usr/local/Cellar/gcc/11.3.0_2/bin/gcc-11 -fdiagnostics-color=always -Wall -Wextra -Wshadow -Wmissing-prototypes -Wstrict-prototypes -Wold-style-declaration -Wold-style-definition -std=c18 -g /Users/sprive/Projects/head-first-c/message_hider.c -o /Users/sprive/Projects/head-first-c/message_hider
/usr/bin/gcc
clang
/usr/bin/gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
评论
encvrypt()
Undefined symbols for architecture x86_64: _encryptx"
encrypt()
encrypt()
_bind()
_