为什么GCC将变量名“linux”视为常量“1”?

如果你在GCC中编译类似下面的代码,将无法通过:

    int main(void)
    {       
      int linux = 5;
      return 0;
    }

使用-E选项检查,你会发现预处理器将上面那段代码处理成了下面这样:

    int main(void)
    {
      int 1 = 5;
      return 0;
    }

为什么会发生这种情况?Stack Overflow上有人解释了其中缘由:

在遥远的过去(ANSI标准确定前),类似unix和vax这样的符号被用做在编译时确定目标平台。那时还没有C语言的官方标准(第一版《C程序设计语言》也尚未出版)。编译器通过错综复杂的#ifdef宏实现针对特定系统的功能。因为那时对变量的使用没有通用规则,编译器的作者们通常会在编译器的实现中使用这些符号,并假定开发者在自己的代码中会避开它们。

1989年ANSI C标准出台后,限制了编译器对符号的使用,编译器中预定义宏的符号只能以两个下划线开头,或者一个下划线后紧接着大写字母。于是,那些默认使用旧预定义符号(例如unix、linux)的编译器就变得不合法了,GCC就是其中之一(最早一版的GCC是1987年发布的)。在编译器的实现中,它将linux当成1。不过,通过类似gcc -std=c90 -pedantic这样的参数,可以让GCC遵循新规范。

顺便说一句,在1987年的国际C语言混乱代码大赛上,“Best One Liner”奖项得主David Korn(他是Korn Shell的作者),就利用了预定义unix宏的特性。他的这一行代码是:

你看得出这行代码的运行结果是什么吗?

理解linux编译工具 gcc、g++、cmake、make、makefile、makelist.txt 关系 总体概括: cmakeList.txt ----->cmake工具---->makefile文件(包含gcc/g++命令)---->make工具---->编译连接源文件 编译器的工作流程: 源码(source code)---->预处理器(preprocessor)---->编译器(compiler)---->汇编程... 阅读详情

相关推荐

GCC中的预处理指令分析

GCC中的预处理指令分析,主要分析了预处理指令是如何实现的。

使用gcc展示完整的编译过程(gcc预处理模式、编译模式、汇编模式、连接模式)

最近在了解 clang/llvm 的时候突然发现一件事:gcc是一个工具集合,包含了或者调用将程序源代码转换成可执行程序文件的所有工具,而不只是简单的编译器。这帮助我对“编译器”有了更深刻的理解,所以写下本文作为记录。从源代码转换成可执行程序的完整过程,也就是我们平时所说的“编译过程”,实际如下(圆角矩形表示代码,矩形表示各种处理器)可以看到从源代码到可执行程序要经过预处理器(preprocessor)、编译器(compiler)、汇编器(assembler)和连接器(linker)或加载器(loader)

ZhongUncle的博客 8280

Vivado时序约束实战:input_delay在高速接口设计中的关键作用

本文深入探讨了在Vivado时序约束中,input_delay对于高速接口设计的关键作用。通过一个RGMII以太网接口调试的实际案例,解释了为何仅靠仿真正确而实际数据采集会失败,并揭示了set_input_delay约束的本质是告知时序分析工具外部芯片的时序关系,而非添加物理延迟。文章详细讲解了如何根据数据手册计算约束值、针对不同采样时钟方案(如移相时钟)进行约束,并指导如何通过时序报告验证约束效果,是解决FPGA高速接口时序问题的实战指南。

ee345的博客 252

在gcc中定义符号常量

http://www.ha97.com/2830.html 还可以在编译命令行中定义符号常量。为此,我们可以简单的在命令行中使用-D选项即可,如下例所示: $ gcc -DTEST_CONFIGURATION test.c -o test 上面的命令与在源文件中加入下列命令是等效的: #define TEST_CONFIGURA

chivalry 1643

英伟达笔试1

本文摘要: 使用NAND2门设计4位奇偶校验发生器,通过15个NAND2门实现4输入异或功能,分三级结构完成奇校验计算。 时序分析公式总结: 建立时间约束:T_cq + T_comb(max) + T_setup + T_skew ≤ T_clk 保持时间约束:T_cq + T_comb(min) + T_skew ≥ T_hold 提供了两段路径的具体时序检查公式和建立违规修复方法 分析32位粘滞累积寄存器Verilog代码: 功能:记录输入数据中出现过的所有1位 每个bit独立实现,复位清零,有效输入时

soulermax的博客 165

【10. Wi-Fi 通用模组-小米 IoT 平台-如何进行硬件调试】

调试APP功能:从米家服务器缓存读取设备状态,等同于米家APP 的环境,开发者使用该调试器可模拟用户使用设备的实际情况,即调试米家 App 中的扩展程序。- 调试固件:调试器从固件读取设备状态,用于调试设备模组固件的某个单项功能,开发者使用该调试器可针对性地调试设备的某个功能。小爱语控测试工具:如果当前产品可被小爱语控,则可以使用该工具调试语控效果。调试APP功能(云端缓存)

tuoyuanO的博客 1041

Linux系统应用(5)——编译器gcc

重点在软件开发的过程中,从源代码到可执行程序的转变是一个复杂且有序的过程,通常包括预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)几个阶段注意这部分内容并没有难度,只需要理解和会使用即可这部分知识其实也并不多,了解.c文件变为可执行程序的过程即可,动态与静态库这里只作为提及,后续学习过程中我们会加深回他的理解,等今后的我们能力充足之后便可以熟知!

2301_80492355的博客 1002

vivado 工程修改芯片型号

vivado工程芯片与实际板子不匹配时,需要修改工程的芯片型号,并对原工程的ip进行同步更新,之后生成新的bit文件,烧录到板子中

k7126685的博客 1万+

gcc编译四个阶段:预处理、编译、汇编、链接

gcc g++ 四个阶段: 预处理、编译、汇编、链接

UUUUTaossienUUUU的专栏 3466

Pytorch实现softmax多分类

PyTorch实现softmax多分类

天涯雨的博客 1387

基于ESP32-S3与模块化设计的立创桌面充电站:从硬件架构到Web控制实战

本文详细介绍了基于ESP32-S3与模块化设计的立创桌面充电站项目,涵盖从硬件架构到Web控制的全流程实战。项目采用模块化设计,支持自由组合快充模块,并通过ESP32-S3实现智能监控,用户可通过本地网页实时查看各接口电压、电流与功率数据。文章重点解析了基板、连接板与充电模块三大核心部件的设计,特别是大电流PCB的“开窗贴铜”处理技巧,并提供了固件刷写与Web控制面板的配置指南。

weixin_36122351的博客 292

输出gcc的编译器内部预设全部常量宏定义

利用gcc编译器的预处理功能,可以输出编译器内部预设全部常量宏定义,对于交叉编译器arm-linux-gcc同样有功能,命令格式 # gcc -E -dM bl.c # arm-linux-gcc -E -dM bl.c 输出的实例如下: [root@jocks ~]# gcc -E -dM bl.c #define __DBL_MIN_EXP__ (-1021) #define

jocks的专栏 5452

腾讯开源SuperSonic:AI+BI如何重塑数据分析?

SuperSonic是腾讯开源的AI+BI平台,融合Chat BI与Headless BI,为制造企业提供实时数据分析。它通过自然语言交互打破数据壁垒,实现生产、库存、质量、供应链等多环节优化,提升决策效率,其开源生态与扩展性助力企业数字化转型与数据价值挖掘。

数据与算法架构提升之路专栏 4535

为什么GCC预处理器将变量名“linux”视为常量“1”?

如果你在GCC中编译类似下面的代码,将无法通过: #include <stdio.h> int main(void) { int linux = 5; return 0; } 使用-E选项检查,你会发现预处理器将上面那段代码处理成了下面这样: int main(void) { int 1 = 5; return 0;...

lispython的专栏 256

10.嵌入式控制器EC实战 GPIO开发流程

文章目录1.General Control Register (GCR),通用控制寄存器,地址0x1602.GPDRA—GPDRJ端口数据寄存器组(共10组)3.Port Control n Registers (GPCRn, n = A0-I7),端口控制寄存器4.GPIO端口编程指导编程步骤端口初始化使用InitGPIOReg数据结构初始化所有端口默认工作模式读取输入引脚的值(STATE_ACin()): IT8502中各个引脚的描述见下表所示: 在嵌入式控制器EC的IT8502主控芯片中,通过芯片的

qq_30135687的博客 2283

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

(测试markdown编辑器)为什么GCC将变量名“linux”视为常量“1”?

如果你在GCC中编译类似下面的代码,将无法通过: #include <stdio.h>; int main(void) { int linux = 5; return 0; } 使用-E检查,你会发现预处理器将上面那段代码处理成了下面这样你好: 在遥远的过去(ANSI标准确定前)这样的符号被用做在编译时确定目标平台。那时还没有C...

lispython的专栏 201

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Linux工具——gcc和gdb

代码编写调试托管一条龙服务,赶紧上车

wzh18907434168的博客 1196

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux中的GDB的作用与GCC的区别

Linux中的GDB的作用与GCC的区别

2302_80908313的博客 1057

linux下gcc、gdb、makefile

GCC 再linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。 gcc编译可以经过四个阶段: (1)预处理:c/c++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”,宏定义命令“#define”,条件编译命令“#if”、“#ifdef”等。预处理就是将要包含(include)的文件插入源文件中、将宏定义展开,根据条件编译命令选

960

【Linux】环境基础开发工具使用——gcc/g++使用

定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make。只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么。这个文件,并把这个文件作为最终的目标文件。

风铃子加油的博客 1601

【Linux】gcc/g++ && gdb 使用

【Linux】gcc/g++ && gdb 使用 1,背景知识   2,gcc 如何完成    1,预处理(进行宏替换)    2,编译(生成汇编)    3,汇编(生成机器可识别代码)    4,连接(生成可执行文件或库文件)    5,函数库    7,静态库和动态库    8,gcc 选项    9,gcc 选项记忆   3,Linux调试器-gdb使用    1,背景    2,命令选项    3,list/l 行号    4,list/l 函

m0_71676870的博客 1090

linux gcc 里面的变量命名的陷阱

linux的gcc编译器自带了很多宏定义,倘若我们的变量跟系统的宏定义相同,编译就会错误。 如下面这段代码: #include int main(int argc,char **argv){ int linux = 10; int unix = 2; return 0; } 运行命令编译 # gcc -o main mian.c 出现如下错误:

把自己当做自己,把别人当做别人;把自己当做别人,把别人当做自己 1199

gcc和gdb的使用——Linux

Linux gcc gdb makefile 知识点

一些七零八碎的知识点 1046

Linux入门教程(gcc和gdb)

路径+可执行文件名 或者 路径+可执行文件名 & (将进程放到后台执行);可以把可执行文件放到 /usr/bin 就可以省略路径了;思考:为什么?ps :/usr/bin ps,ls,pwd (先了解)

Sonder_autistic的博客 748

Linux:gcc编译器 | 动静态库的创建与使用

方法总比问题多

kimsaul的白给岁月 1930
上一篇: 创业是否只是年轻人的专利?
下一篇: Facebook开始在生产环境中使用D语言
923940cub
博客等级 码龄17年 121粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值