【问题标题】:Undefined reference when compiling libPNG example编译 libPNG 示例时未定义的引用
【发布时间】:2019-03-18 16:51:14
【问题描述】:

我正在尝试this libPNG 示例,但编译失败。我用gcc -lm -lpng makePNG.c编译得到如下错误:

/tmp/ccgGO8zw.o: In function `writeImage':
makePNG.c:(.text+0x360): undefined reference to `setRGB'
collect2: error: ld returned 1 exit status

我删除了函数定义并简单地移动了函数,以便它们按以下顺序排列:

void setRGB(png_byte *ptr, float val)
int writeImage(char* filename, int width, int height, float *buffer, char* title)
float *createMandelbrotImage(int width, int height, float xS, float yS, float rad, int maxIteration)
int main(int argc, char *argv[])

它奏效了。我的问题是:为什么它以前不起作用? SetRGB 是在 writeImage 之前定义的,那么 'setRGB' 引用怎么可能是未定义的呢?

编辑:

我忘了提一些我现在意识到非常重要的事情。我从 setRGB 函数中删除了 'inline' 关键字。我尝试使用 inline 关键字进行编译,它有相同的错误消息。很明显,我的问题与 inline 关键字有关,而不是我最初认为的前向声明...

【问题讨论】:

  • 示例编译和构建很好看Resulting .png尝试gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o libpngex libpngex.c -lm -lpng然后运行./libpngex output.png
  • inline 关键字只是对编译器的“提示”,它可以内联函数。不能保证它会做到。但是,函数declaration 和函数definition 之间必须保持一致。您不能将inline 放在一个上而不是另一个上——它们将被视为两个不同的函数。
  • 对不起@sam,你很困惑。我的来源名称是libpngex.c。只需使用您的makePNG,例如gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o makePNG -lm -lpng makePNG.c 然后运行./makePNG somepng.png
  • 您发布的是gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o libpngex makePNG.c -lm -lpng makePNG.c。删除其中一个makePNG.c,您的输出将位于libpngex 或删除libpngex 并从第一个'.c' 中删除'.c'
  • 如果您仔细查看您发布的gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o libpngex makePNG.c -lm -lpng makePNG.c 的命令,您包含了makePNG.c 两次。这就是导致‘code’ might be clobbered... 警告的原因。

标签: c libpng


【解决方案1】:

感谢 David C. Rankin,我找到了一个可以编译它的命令。 gcc -Ofast -lm -lpng makePNG.c 有效,因为它包含 -Ofast 选项。这是man gcc中对该选项的描述:

-Ofast

无视严格的标准合规性。

-Ofast 启用所有 -O3 优化。它还支持并非对所有符合标准的程序都有效的优化。它打开 -ffast-math 和 Fortran 特定的 -fno-protect-parens 和 -fstack-arrays。

我怀疑作者使用 inline 的方式不符合 c 规范,这就是为什么没有这个选项它不会编译的原因。不用说,编写不符合 c 标准的代码是绝对不行的。

编辑:

证明 -Ofast 选项是罪魁祸首:

$ gcc -Ofast -lm -lpng makePNG.c
$ gcc -lm -lpng makePNG.c
/tmp/cc2JlymP.o: In function `writeImage':
makePNG.c:(.text+0x360): undefined reference to `setRGB'
collect2: error: ld returned 1 exit status
$ 

【讨论】:

  • 实际问题在于setjmp(png_jmpbuf(png_ptr))的使用。看看man page 中的最后一句“setjmp()sigsetjmp() 使程序难以理解和维护。如果可能,应使用替代方案。”此代码将使用-O2 或更高的优化干净地编译。在libpng12 中对libpng 进行了更改,后来隐藏了需要使用png_jmpbuf 的实际png 结构成员。
  • 你是对的,它甚至可以在我的机器上使用 -O 优化。
猜你喜欢
  • 2012-05-30
  • 2021-08-17
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
相关资源
最近更新 更多