为什么 C 允许缺少函数声明?

2024-03-26

今天我们遇到了一个不寻常的现象,一位同事在他的代码中调用了一个正常运行的函数,这触发了 libc (gethostbyname) 中的段错误。令人费解的是,相同的函数在同一运行时的其他源文件中运行没有问题。令人惊讶的是,当使用 valgrind 时,段错误消失了,事实上,它与 valgrind 完美配合,没有报告任何错误。

为了安抚编译器之神,我们做出了很多牺牲,最终意识到调用该函数的源文件中缺少声明该函数的头文件。一旦我们添加了这个,一切就正常了。

为什么 gcc/ld 没有生成错误(甚至警告)来指示该函数未被识别?为什么它可以与 valgrind 一起使用?

Thanks.


因为您没有使用正确的警告选项,例如-Wall -Wmissing-prototypes -Wstrict-prototypes。默认情况下,gcc 在接受的内容上相当自由。 C语言(至少C89)有这样的概念隐式函数声明,其中没有原型的函数具有从函数调用中第一次使用派生的返回类型和参数列表,并且缺少该列表,它返回 int 并接受未指定但固定数量的参数(即不能是可变参数函数) 。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 C 允许缺少函数声明? 的相关文章

  • 为什么 GCC 交叉编译不构建“crti.o”?

    在尝试为arm构建gcc 4 x x交叉编译器时 我陷入了缺失的困境crti o文件在 BUILD DIR gcc子目录 An strace在顶层Makefile表明编译后的xgcc正在调用交联器ld with crti o 作为一个论点
  • 这个反斜杠在这段汇编代码中起什么作用?

    我不确定这些推线有什么区别 修剪下来来自 Linux 的 x86 entry calling h https github com torvalds linux blob 241e39004581475b2802cd63c111fec43b
  • 使用 mingw32 在 Windows 上构建 glew 时“DllMainCRTStartup@12”的多个定义

    我关注了这个主题 使用 mingw 使建筑物在 Windows 上闪闪发光 https stackoverflow com questions 6005076 building glew on windows with mingw 6005
  • 编译器如何实现位域运算?

    当询问如何做的问题时包裹 N 位有符号减法 https stackoverflow com questions 8309538 integer subtraction with wrap around for n bits我得到了以下答案
  • 为什么是 ”\?” C/C++ 中的转义序列?

    C C 中有四种特殊的非字母字符需要转义 单引号 双引号 反斜杠 和问号 显然是因为它们有特殊的含义 对于单身char 对于字符串文字 对于转义序列 但为什么是 其中之一 我今天读了教科书上的转义序列表 我意识到我已经never逃脱了 以前
  • 用户泄漏、libc++ 泄漏或误报

    我正在使用 clang 编译器和 libc 标准库在 C 11 中的 mac 上构建动态库 当我在链接到动态库的测试代码上运行 valgrind 时 我得到一块肯定丢失的内存 这是 valgrind 报告 45659 36 bytes in
  • Pyaudio 安装错误 - “命令‘gcc’失败,退出状态 1”

    我正在运行 Ubuntu 11 04 Python 2 7 1 并想安装 Pyaudio 于是我跑了 sudo easy install pyaudio 在终端中 进程退出并显示以下错误消息 Searching for pyaudio Re
  • GCC 5 及更高版本中的 AVX2 支持

    我编写了以下类 T 来加速操作 使用 AVX2 的 字符集 然后我发现它不起作用 gcc 5 及更高版本当我使用 O3 时 谁能帮我追踪到一些编程结构 已知不适用于最新的编译器 系统 该代码的工作原理 底层结构 bits 是一个 256 字
  • 在GCC中添加父目录的包含路径

    我想将父目录中的文件包含在我正在处理的项目中 所有的头文件都在父目录中 有没有办法在命令行上使用 I 来搜索父目录中的包含而不使用绝对路径 我知道我可以使用 makefile 解决这些问题 并且我可能最终会这样做 但我想知道是否有一个可以使
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • 链接器问题 - 未定义的引用

    我的编译器有问题 告诉我有一个 未定义的引用 我想在库中使用的函数 让我分享一些有关该问题的信息 我正在用 gcc 交叉编译 C 语言 我正在调用一个库函数 该函数通过包含的标头访问 其中包含另一个标头 其中包含原型 我已经使用 I 包含了
  • constexpr lambda / ‘x’ 不命名类型;您指的是“x”吗?

    我正在尝试使用 C 17 的 constexpr lambda 来获取编译时字符串 include
  • 链接器错误无法在库中找到符号名称

    g GCC 4 7 2 3 7 6 201 fc18 x86 64 1 SMP Mon Feb 4 15 54 08 UTC 2013 x86 64 x86 64 x86 64 GNU Linux Fedora release 18 Sph
  • netdb.h 未正确链接

    我正在尝试编译这个程序 如引用的Beej 的网络编程指南第 19 页 include
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • 如何编译一个简单的 multiboot2 裸机可执行文件?

    我想开始写一个操作系统内核 然后 我找到了一个document http nongnu askapache com grub phcoder multiboot pdf引入 multiboot2 规范 有三个示例代码文件 名为boot S
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • valgrind 在 Raspberry Pi 上返回未处理的指令

    我最近一直在尝试在运行 Debian GNU Linux7 0 喘息 的树莓派 型号 b 上使用 valgrind 来调试分段错误 每次我在编译的 C 程序上运行 valgrind 时 都会得到类似以下内容的信息 disInstr arm
  • gcc 删除内联汇编代码

    看起来 gcc 4 6 2 删除了它认为函数中未使用的代码 test c int main void goto exit handler asm volatile jmp 0x0 exit return 0 拆解main 0x0804840
  • 如何将 elf 解释器(ld-linux.so.2/ld-2.17.so)构建为静态库?

    如果我的问题不准确 我深表歉意 因为我没有太多 Linux 相关经验 我目前正在构建一个 Linux 从头开始 主要遵循 linuxfromscratch org 版本的指南 7 3 我遇到了以下问题 当我构建可执行文件时 获取一个称为 E

随机推荐