gpt4 book ai didi

c++ - 与链接静态库相比,从源代码构建时,为什么 gcc 会产生不同的结果?

转载 作者:太空宇宙 更新时间:2023-11-03 10:23:35 25 4
gpt4 key购买 nike

我有一个 C++14 文件,my.cpp,我试图从其中使用一个名为 open62541 的 C99 库。对于后者,完整的源代码 open62541.c/.h 和库 libopen62541.a 都存在。在 my.cpp 中,我包含了 open62541.h,我使用的是 C++ 特定代码(例如 iostream),所以从技术上讲,我混合使用了 C 和 C++。

我可以通过引用libopen62541.amy.cpp编译成功:

gcc -x c++ -std=c++14 -Wall my.cpp -l:libopen62541.a -lstdc++ -o out

这不会输出任何警告,并创建一个可执行文件 out

但是,如果我尝试仅使用源代码进行编译:

gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out

我收到很多 ISO C++ 警告(例如“ISO C++ 禁止将字符串常量转换为 'char'*”)和一些“跳转到标签”错误源自open62541.c,导致编译失败。

我可以通过使用 -fpermissive 开关使编译成功:

gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -fpermissive -o out

仍然输出很多警告,但成功创建了可执行文件。但是,我不确定这样做是否是个好主意。

也许值得一提的是open62541.h在开头考虑了C++:

#ifdef __cplusplus
extern "C" {
#endif
  1. 鉴于与 open62541 库代码捆绑在一起的 .a 库应该是从同一来源构建的,为什么前两种方法在警告和错误方面不一致生成?为什么一个有效而另一个无效?

  2. 一种方法(链接 .a 与引用 .c)是否应该优于另一种方法?我的印象是它们应该是等效的,但显然它们不是。

  3. 在这种情况下使用 -fpermissive 是否更像是一种可以掩盖潜在问题的 hack,因此应该避免?

最佳答案

您看到的错误(和警告)是 C++ 编译器在编译 C 代码时输出的编译错误(和警告)。

例如,在 C 中 "literal"类型为 char[]而在 C++ 中它的类型是 const char[] .

你会得到一个 C++ 编译器构建 libopen62541.a来自 open62541.c ,您会看到相同的错误(警告)。但是 C 编译器可能会接受它(取决于该 C 源文件的状态)。

另一方面,当你编译my.cpp并将其链接到 libopen62541.a ,编译器看不到有问题的 C 代码,因此没有错误(警告)。


从这里开始,您基本上有两个选择:

  1. 如果原样适合您,请使用预编译库

    g++ -std=c++14 -Wall -Wextra -Werror my.cpp -lopen62541.a -o out
  2. 如果您需要修改它,请先编译库的代码

    gcc -Wall -Wextra -Werror -c open62541.c
    g++ -std=c++14 -Wall -Wextra -Werror -c my.cpp
    g++ open62541.o my.o -o out

关于c++ - 与链接静态库相比,从源代码构建时,为什么 gcc 会产生不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50719736/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com