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

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

#include <stdio.h>
int main(void)
{       
    int linux = 5;
    return 0;
}

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

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

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

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

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

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

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}

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

C++预处理器深度解析:从宏定义到条件编译的工程实践 预处理器是C/C++编译流程中的关键环节,它在编译器进行语法分析前对源代码进行文本处理。其核心原理是通过宏定义、文件包含和条件编译等指令,对源代码进行文本替换和组织,生成可供编译器直接处理的翻译单元。这一机制在工程实践中具有重要价值,能够实现跨平台代码管理、编译期配置和代码生成等功能。在C++开发中,预处理器常用于实现头文件守卫、调试日志系统和平台抽象层等场景。例如,通过 #define 宏定义和 #ifdef 条件编译指令,开发者可以灵活控制不同构建配置下的代码行为,而 __FILE__ 和 __LINE 阅读详情

相关推荐

用ADSP-21569+SigmaStudio打造音频处理系统:从硬件连接到实时调参实战

本文详细介绍了如何利用ADSP-21569 DSP芯片和SigmaStudio图形化编程工具构建高性能音频处理系统。从硬件接口配置、信号流设计到实时参数调试,提供工业级开发中的实用技巧,包括低延迟优化、动态参数插值等关键技术,帮助开发者快速实现专业音频处理方案。

9o8p7i6u5y的博客 979

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

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

ZhongUncle的博客 8280

AI气象预报:数值模式融合与短临预警的工程实践

气象预报正经历从物理推演到数据驱动的认知范式转变。AI气象预报并非替代传统数值模式,而是通过数值模式融合弥补其在参数化误差、初值敏感性和计算效率上的固有瓶颈。其技术价值在于提升短临预警时效性与空间精度,支撑航空调度、电力调控、防洪应急等关键场景。实践中需兼顾物理一致性、可解释性与业务系统兼容性,避免纯黑箱建模带来的外推失效与不确定性缺失风险。本文聚焦AI作为超分辨率引擎、误差矫正器和短临加速器的三类落地路径,解析HEALPix投影、多尺度图建模、轻量级U-Net等核心适配方法。

weixin_28221501的博客 298

在gcc中定义符号常量

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

chivalry 1643

从USB 2.0到USB 3.x:Synopsys SVT USB VIP配置避坑与接口选择指南

本文详细解析了从USB 2.0到USB 3.x的Synopsys SVT USB VIP配置要点,涵盖协议版本选择、物理接口匹配及UVM层次化架构实现。重点介绍了layering sequence的配置技巧和常见问题解决方案,帮助验证工程师高效避坑并优化验证流程。

weixin_42653691的博客 238

POST 接口,将参数拼接到 URL 上,而不是将其作为表单数据发送

POST 接口,将参数拼接到 URL 上,而不是将其作为表单数据发送

pig_ning的博客 3143

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

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

2301_80492355的博客 1002

基于单片机的自动喷淋系统设计【毕业设计】

随着人民生活质量提高与生活节奏的加快,城市居民对于花草绿植的家庭培养与装饰需求增加,随之因浇灌植物的需要,智能浇花系统的市场逐渐扩大。现有自动浇花系统大部分只能通过设置固定浇水时间而难以实现适时、适量浇水,或在植物环境土壤含水量低时进行报警而并不能实际补水。为克服局限性而设计以单片机为控制中心的自动浇花系统。通过湿度传感器检测目标植物环境土壤湿度数据,再经ADCO832将其放大转换为数字量,由单片机读取输出向LCD1602 显示屏显示并通过比对键盘向单片机所设置的湿度范围而利用中断服务程序进行补水需求判断。

qq_48771816的博客 1711

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

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

UUUUTaossienUUUU的专栏 3466

SAP S4 HANA:按单生产(MTO)场景中的COGS分割

本文介绍了SAP S/4HANA中提供的各种选项,以在销售订单/商品是按订单生产(以下称为MTO)生产流程中的成本对象时,在基于帐户的COPA环境中报告COGS分割信息。

adam915的博客 1191

亚马逊跨境电商选品数据分析:Python爬虫实战指南

本文将带领大家构建一套完整的亚马逊选品数据采集与分析系统,使用最新的Python技术栈,从零开始爬取亚马逊商品数据,并进行深度分析。

2201_76125261的博客 299

输出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

《QGIS快速入门与应用基础》079:KML/KMZ格式:Google Earth兼容

KML/KMZ是专为地理可视化设计的空间数据格式,原生兼容Google Earth,支持点线面要素标注与多媒体集成。KML为XML文本格式,KMZ是其压缩版本。该格式优势在于可视化表现力强、跨平台共享便捷,适合地理标注、路线分享等场景,但存在属性支持弱、大数据量处理效率低等局限。QGIS中可便捷加载和导出KML/KMZ数据,需注意编码设为UTF-8、勾选"导出样式"以保留可视化效果。建议中小规模标注数据使用KMZ格式,确保关联资源完整,提升共享效率。

LuckyHanMo的博客 766

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

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

yangluoning的专栏 1068

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

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

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

lispython的专栏 201

jre9下载 jdk9

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

Linux 编程与调试工具 gcc:GNU 编译器集合

在 Linux 开发环境中,编译器是每个开发者都离不开的工具。而 `gcc`(GNU Compiler Collection)作为 Linux 上最为常见的编译器之一,凭借其强大的功能和广泛的支持,成为了 C、C++、Fortran 等编程语言的首选工具。本文将深入介绍 `gcc` 的基本使用、功能以及在编程与调试过程中的重要作用,帮助开发者更高效地进行开发和调试。

919

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

「Linux基础开发工具」gcc和gdb

在学习编程的路途中,你是否有了解过自己使用的编译器呢,这里说的编译器指的可不是vscode或vs2022这样的ide,如果你还没有了解过编译器,本文将为你介绍编译器中最著名的gcc(???我在写什么)gcc是linux下的一款开源的编译器软件,全程,可用于编译多种编程语言,包含C++、C、Java等。

CaTianRi的博客 136

Linux命令-GCC命令(编译器套件,支持C、C++、Fortran等多种编程语言)

GCC是Linux开发者必须掌握的核心工具。核心要点包括:使用-o指定输出文件;养成-Wall和-Werror的好习惯;调试时加-g,发布时选择优化级别(如-O2多文件项目推荐分步编译;正确使用-I-L-l处理头文件和库。

RisunJan的博客 1324

Linux基础——GCC编译器和GDB调试

Linux基础——GCC编译器和GDB调试

月半 月半的博客 1225

Linux下C语言开发入门:从GCC编译到Makefile构建全解析

在软件开发领域,编译是将高级语言代码转换为机器可执行指令的核心过程。其基本原理涉及预处理、编译、汇编和链接四个关键阶段,每个阶段都承担着特定的代码转换任务。这一技术价值在于,它不仅是程序运行的必经之路,更是理解计算机系统工作原理、进行性能优化和跨平台开发的基础。在Linux环境下,GCC作为标准的编译器工具链,广泛应用于C/C++项目的构建。通过掌握GCC的基本用法,开发者可以深入理解编译链路,为后续使用Makefile自动化构建、处理多文件项目以及解决常见的编译错误(如隐式函数声明或动态链接库缺失)奠定坚

weixin_34198881的博客 308

事实证明:linux总是Number 1(转载)

为什么80%的码农都做不了架构师?>>> ...

weixin_34009794的博客 97

[Linux]GCC编译选项

<br />gcc/g++在执行编译工作的时候,总共需要4步 <br /> 1.预处理,生成.i的文件[预处理器cpp] <br /> 2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs] <br /> 3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as] <br /> 4.连接目标代码,生成可执行程序[链接器ld] <br /> 参数详解 <br /> -c 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件    <br /> eg: gcc -c hel

xiaohuoma7620的专栏 682

Linux-Chap5-C语言编程

Linux中的C语言程序设计 C语言:是Linux中最常用的系统编程语言之一。功能极其强大的程序设计语言。包含直接操作内存和硬件的底层计算语句,也包含高级语言所具有的数据结构、控制语句、函数调用等功能。是一门编译语言,而不是脚本语言。可使用Linux函数库和系统调用。 如何编写和执行C语言程序:使用任何文本编辑器编写C语言程序源文件.c。使用C语言编译器gcc编译源文件,生成独立可执行文件。在遇到错误时,编译器会给出错误信息停止编译,不会生成目标文件。 gcc编译格式: gcc 源文件名 #

Pinkray_07的博客 513

GCC编译器CFLAGS、LDFLAGS详解

在Linux开发中,我们经常用到Makefile来管理代码,进行代码的编译。一般的Makefile中都会包含CFLAGS、LDFLAGS两个选项,用于指导编译和链接的过程。有时候我们总是不注意这两个选项的一些区别,将某些编译选项放到链接选项中,导致编译生成的程序出现无法预知的问题;

小嵌同学的博客 2万+

【视频】Linux高级程序设计01.1开发工具及gcc gdb

【课程笔记】 Linux 下编辑调试工具,gcc,gdb。 把高级语言编译成二进制可执行代码的工具。 需要经历四个步骤: (1) 预处理:去掉注释,进行宏替换(#define相关),头文件(#include)包含等工作 gcc -E test.c -o test.i (2) 编译:不同平台采用的汇编语言不一样。编译将高级语言编译成汇编语言。 gcc -S te...

weixin_30471065的博客 77
下一篇: (测试markdown编辑器)为什么GCC将变量名“linux”视为常量“1”?
923940cub
博客等级 码龄17年 121粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值