加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何找出gcc和g产生不同代码的原因

发布时间:2020-12-16 10:25:25 所属栏目:百科 来源:网络整理
导读:是否有可能看到 gcc和g编译过程背后发生了什么? 我有以下程序: #include stdio.h#include unistd.hsize_t sym1 = 100;size_t *addr = sym1;size_t *arr = (size_t*)((size_t)arr + (size_t)addr);int main (int argc,char **argv){ (void) argc; (void) ar
是否有可能看到 gcc和g编译过程背后发生了什么?
我有以下程序:

#include <stdio.h>
#include <unistd.h>

size_t sym1 = 100;
size_t *addr = &sym1;

size_t *arr = (size_t*)((size_t)&arr + (size_t)&addr);

int main (int argc,char **argv)
{
    (void) argc;
    (void) argv;

    printf("libtest: addr of main(): %pn",&main);
    printf("libtest: addr of arr: %pn",&arr);

    while(1);
    return 0;
}

当使用gcc时出错时,为什么用g生成二进制文件而不出错?
我正在寻找一种方法来追踪使它们表现不同的方法.

# gcc test.c -o test_app
test.c:7:1: error: initializer element is not constant
# g++ test.c -o test_app

我认为原因可能是gcc使用cc1作为编译器而g使用cc1plus.
有没有办法更准确地输出实际做的?
我试过使用-v标志,但输出非常相似.是否有不同的标志传递给链接器?
比较两个编译过程并发现其中的差异的最简单方法是什么?

解决方法

在这种情况下,gcc不会产生任何结果,因为您的程序无效C.正如编译器所解释的那样,初始化元素(用于初始化全局变量arr的表达式)不是常量.

C要求初始化表达式是编译时常量,以便局部变量的内容可以放在可执行文件的数据段中.这不能用于arr,因为在链接时间之前不知道所涉及的变量的地址,并且动态链接器不能简单地填充它们的总和,就像addr1的情况一样. C允许这样,因此g生成初始化代码,用于计算非常量表达式并将它们存储在全局变量中.此代码在调用main()之前执行.

可执行文件cc1和cc1plus是编译器实现的内部细节,因此与观察到的行为无关.相关的事实是gcc期望有效的C代码作为其输入,并且g期望有效的C代码.你提供的代码是有效的C,但不是有效的C,这就是为什么g编译它而gcc没有.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读