c - 忽略包含文件时,拆分源没有输出,但也没有警告

标签 c gcc dependencies warnings

我在调用 gcc 时遇到了一个问题,如果我省略了库 .c 文件,我就不会从二进制文件中得到任何输出(意外的行为变化),但由于这是一个缺失的依赖项,我有点预计编译会失败(或至少发出警告)...

此问题的示例来自 Head First C 第 185 页(但不是勘误表,请参阅下面我的编译错误步骤):

加密.h:

void encrypt(char *message);

加密.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
  1. 即使我添加了 -Wall -Wextra -Wshadow -g,构建也令人惊讶地成功。
  2. 同样令人惊讶的是,它默默地失败了,加密()函数没有输出:
$ ./message_hider < ./encrypt.h 
$ 

我的海湾合作委员会是:

$ /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 文件的信息,是否可以强制发生硬错误?

最佳答案

正如我在(拼写错误的)评论中指出的:

There is probably a function encrypt() in the system library.

在 Mac 上,man -s 3 encrypt显示:

CRYPT(3) BSD Library Functions Manual CRYPT(3)

NAME
crypt, encrypt, setkey -- DES encryption

SYNOPSIS

#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 的系统上使用。奇怪的是,如手册页摘录所示,这些函数是在单独的 header 中声明的 - <unistd.h> 对于 encrypt() <stdlib.h> 对于 setkey() 。这种脱节可能有一个很好的(足够的)历史原因。

您应该收到有关函数未声明的编译器警告 - 如果没有,则可能是使用 C90 标准进行编译。这是很古老的事了,不应该再被教授了;您需要学习 C11 或 C18(几乎相同)。

自 C99 起,C 标准要求函数在使用前声明 - 您可以定义 static函数无需预先声明,但所有其他函数( main() 除外)应在使用或定义之前声明。您可以使用 GCC compiler warning options-Wmissing-prototypes -Wstrict-prototypes (与 -Wold-style-declaration-Wold-style-definition 一起)触发警告。其中,-Wold-style-declaration-Wextra 启用(-Wall 没有)。请注意:如评论中所述,clang不支持-Wold-style-declaration尽管真正的 GCC(不是 Apple 的 clang 伪装成 gcc )确实支持它。

关于c - 忽略包含文件时,拆分源没有输出,但也没有警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73346159/

相关文章:

使用 gcc 编译 Linux 设备驱动模块

c++ - 使用在当前函数下面声明的函数(允许循环依赖)?

c - 将数组读入字符串的最快方法

c - 谷歌应用引擎的 GCC

c - C 中整数检查的意外行为

gcc - GCC 生成的 ARM 和 x86 汇编代码的区别

java - GCC 中的外部 "Java" block

java - 查找最小必要的 java 类路径

php - 单元测试中的依赖关系

c - 从文件读取内容时出现段错误