gcc编写翻译错误表,C中的预编写翻译宏定义

By admin in 美高梅手机版4858 on 2019年3月18日

转载:

 

【引用 《智能家用电器气控制制技能》补助文书档案 
那里有分外HTML版的,很实用好查,但正是不可能下载成CHM版的,本地是不能够用啊。】

C中的预编写翻译宏定义

conversion from %s to %s not supported by iconv”
iconv 不援救从 %s 到 %s 的更换”

代表字符串:

1.#operator not followed by macro argument name
“#”运算符后无宏变元名。在宏定义中,”#”用于标志一宏变元是四个串,因而,在”#”前边总得要追随贰个宏变元名。
2.’xxxxxxxx’not an argument
‘xxxxxxxx’不是函数参数。在原程序大校该表识符定义为二个函数,但他没有在函数表中冒出。
3.Ambiguous symbol ‘xxxxxxxx’
二义性符号’xxxxxxxx’。多个或八个以上结构的某一域名相同,但它们的遍移、类型不相同,因而,在变量或表明式中用该域但未带结构名时,,就会发出二义性。在那种气象下,须求修改域名,或在引用时抬高协会名。
4.Argument # missing name
参数#名丢失。参数名已退出用于定义函数的函数原型。C语言规定,假如函数以原型定义,该函数必须含有全体的函数名。
5.Argument list error
参数表语法错误。C语言规定,函数调用的各参数之间必须以逗号分隔,并以右括号甘休,若源文件中包括3个其后不是逗号也不是右括号的参数,则会并发本错误。
6.Array bounds missing
数组的底限符“]”丢失。在源文件中定义了三个数组,但此数组没有以右方括号甘休,则会并发本错误。
7.Arraysize too large
数首席营业官度太长。定义的数组太长,可用内部存款和储蓄器不够。
8.Assembler statement too long
汇编语句太长。C语言规定,内部汇编语句最长无法超越480字节。
9.Bad configuration file
布置文件不可信赖。TURBOC.CFG配置文件中富含不是合适命令行采纳项的非注释文字。C语言规定,配置文件命令选拔项必须以一短横线伊始。
10.Bad file name formart in include directive
含蓄指令普通话件名格式不正确。包罗文件名必须用双引号或尖括号括起来,不然将现出本错误。假使利用了宏,则发出的扩张文本也不正确。
11.Bad ifndef directive syntax
ifdef指令语法错误。#ifdef必须以单个标识符作为该指令的体。
12.Bad ifndef directive syntax
ifndef指令语法错误。#ifndef必须以单个标识符作为该指令的体。
13.Bad undef directive syntax
undef指令语法错误。#undef必须以单个标识符作为该指令的体。
14.Bad file size syntax
位字段长语法错误。二个位字段长必须是在1-拾二位的常量表明式。
15.Call of non-function
调用未定义的函数。正被调用的函数未定义,常常是出于不科学的函数申明或函数名拼写错所导致
16.Cannot modify a const object
不能够改改贰个常量对象。对定义为常量的指标进行不合规的操作(如对常量进行赋值)会时有发生此错误。
17.Case outside of switch
Case
出现在Switch的外围。编写翻译程序意识Case语句在switch的外侧,日常是由于括号不合作所导致。
18.Case statement missing
Case语句漏掉。Case语句必须含有四个以冒号甘休的常量表明式。大概的案由是丢了冒号或在冒号前多了其他符号。
19.Cast syntax error
Cast语法错误。大概在Cast中涵盖了一部分不得法的标记。
20.Character constant too long
字符常量太长。
21.Compound statement missing
复合语句漏掉。编写翻译程序扫描到源文件末尾时,为意识停止大括号,常常是出于大括号不匹配造成。
22.Conflicting type modifiers
花色修饰符争论。对同一指针只好定义一种变址修饰符(如near或far);而对于同一函数也只好交给一种语言修饰符(如cdecl、pascal或interrupt)
23.constant expression repuried
渴求常量表明式。数组的大大小小必须是常量,本错误经常是由于#define常量的拼写错误造成。
24.could not find file ‘xxxxxxxx’
找不到文件’xxxxxxxx’。编写翻译程序找不到命令行上交给的文书。
25.declaration missing
证实漏掉“;”。在源文件中包罗了叁个struct或union域注脚,但背后漏掉了分号(;)。
26.declaration needs type or storage class
注脚必须给出类型或存款和储蓄类。如以下表明是荒唐的:i,j;
27.declaration syntax error
表明出现语法错误。在源文件中,有个别表明丢失了某个符号或有多余的号子。
28.default outside of switch
defaul在switch         外出现。这么些指鹿为马经常是由于括号不匹配造成。
29.define directive needs an identifer
define指令要求求二个标识符。#define前边的率先个非空格符号必须是3个标识符,若编写翻译程序意识一些任何字符,则产出本错。
30.division by zero
除数为零。在源文件中的表明式中现身除数为零的情况。
31.do statement must have while
do语句中务须求有while
32.do-while statement missing(、)、;
do-while语句中漏掉”(、)、;”
33.duplicate case
case的气象不唯一。switch语句中各类case必须有3个唯一的常量表明式。
34.enum synatx error
enum域法出现谬误。enum表明的标识符表的格式不对。
35.enumeration constant syntax error
枚举常量语法错误。赋给enum类型变量的表述式值不是常量。
36.error directive:xxxx
error指令:xxxx.源文件处理#error指令时,展现该指令给出的新闻。
37.error writting output file
写输出文件出错。经常是由于磁盘空间不够造成。
38.expression stntax
表明式语法错误。如:在表达式中再三再四出现多个操作符、括号不般配或干涸括号、前一语句漏掉了分店等。
39.extra parameter in call
调用时出现多余参数。在调用一函数时,实际的参数个数多于函数定义中的参数。
40.extea parameter in call to xxxxxxxx
调用“xxxxxx”函数时出现了剩余的参数。当中该函数由原型定义。
41.file name too long
文本名太长。#include指令给出的文本名太长,编写翻译程序不能够处理。DOC下的公文名不能够超过陆17个字符。
42.for statement missing();
for 语句漏掉“();”
43.function call missing)
函数调用贫乏“)”。
44.function definition out of place
函数定义地方不当。函数定义不可能出想在另一函数内。函数内的其他表达,只要以近乎于带三个参数表的函数早先,就被认为是八个函数定义。
45.function doesn’t take a vatiable number of argument
函数不接受可变的参数个数。源文件中的有些函数内选择了va-start宏,此函数不可能接受可变多少的参数。
46.goto statement missing lable
goto语句缺乏标号。在goto关键字后要求求有一个标识符。
47.if statement misslng()
if语句贫乏“()”
48.illegal character (0xXX)
违规字符串(0xXX)。编译程序意识输入文件中有不法字符,已十六进制打字与印刷该字符。
49.illegal initialzation
非法开头化。初阶化必须是常量表明式后一大局变量extern或static的地点减一常量。
50.illegal octal digit
不法八进制数。编写翻译程序意识在二个八进制常数包括了非八进制数字符号(如8或9)。
51.illegal pointer subtraction
不法指针相减。那是出于计算以一个指针变量减去一个指针变量而造成的。
52.illegal structre operation
私行己组建织操作。结构只好使用“.”、取地址“&”和赋值操作符“=”,或当作函数的参数字传送递。当编写翻译程序意识结构接纳了别样操作符时出现本错误。
53.illegal use of floating point
不法的浮点运算。浮点运算操作数不容许现身在运动、按位逻辑操作、条件(?:)、直接(*)以及其余一些操作符中。
54.illegal use of point
地下利用指针。指针只可以在加、减、赋值、相比、直接(*)或尖头(->)操作中采取。
55.improper use of a typedef symbol
typedef符号使用不当。源文件中动用了二个标志,符号变量应在二个表明式中冒出。检查一下此标志的认证和大概的拼写错误。
56.in-line assembly not allowed
不容许内部汇编语句。源文件中包括有直接插入的汇编语句,若在合龙环境下进展编写翻译,那出现本错误,必须选择TCC命令行来编写翻译该文件。
57.incompatible storage class
不相容的存款和储蓄类。源文件的贰个函数定义使用了extern关键字,而唯有static(或根本未曾存款和储蓄类型)是允许的。
58.incompatible type conversion
不相容的类型转换。源文件中准备把一类别型转换到另一种档次,但那二种是不相容的,如函数与非函数之间的转换、一种结构或数组与一种标准项目间转移、浮点数与指针间转移。
59.incorrect command line argunent:xxxxx
不科学的一声令下参数:xxxxxxxx
60.incorrect cinfiguration file argunent:xxxxx
不科学的文书参数:xxxxxx。编写翻译程序认为该配置文件是私下的,此时可检查一下前面的短横线(_)。
61.incorrect number format
不得法的数量格式。编译程序意识在十六进制数中冒出十六进制小数点。
62.incorrect use of default
default的不得法使用。编写翻译程序意识default关键字后贫乏分号。
63.initializer syntax error
早先化语法错误。初阶化进度中缺少或多了一操作符,括号不合营,或别的一些不健康状态。
64.invalid indrection
失效的直接运算。间接运算符(*)供给非空指针作为操分量
65.invalid macro argument separator
不行的宏参数分隔符。在宏定义中,各参数必须用逗号分割。编写翻译程序意识在参数名背后有其余违规字符
66.invalid pointer sddition
不行的指针相加。原程序中间试验图将八个指针相加。
67.invalid use of arrow
箭头使用错。在箭头操作符(->)后务必跟一标识符
68.invalid use of dot
点选取错。在店操作符(.)后务必跟一标识符
69.lvalue required
请求赋值。赋值符操作的左侧必须是二个地点表达式,包蕴数值变量、指针变量、结构引用域、直接指针或数组分量。
70.macro argument syntax error
宏参数语法错误。宏定义中的参数必须是二个标识符。编写翻译程序意识所需的参数不是标识符号的字符,则产出本错误。
71.mxcro expansion too long
宏扩大太长。2个宏扩展不可能多于409陆个字符。当宏递归扩充自小编时,常出现本错误。宏不可能对本人进行扩充。
72.         may compile only one file when an output file name is
given
交给的叁个出口文件名时,或者只编写翻译二个文书。在命令编写翻译时,若使用-o选用,则至于需2个出口文件名。此时,只编写翻译第一个文件,其余文件被忽视。
73.         mismatch number of parameters in definition
概念中参数个数不般配。定义中的参数和函数原型中提供的新闻不匹配。
74.         misplaced bresk
break地方不当。编写翻译程序意识break语句的switch语句或循环结构外
75.         misplaced continue
continue地点错。编写翻译成促发现continue语句在循环结构外
76.         misplsced decimal point
十进制小数点地点错。编译程序意识浮点常数的指数部分有三个十进制小数点
77.         misplace else
else
地方错。编写翻译程序意识else语句缺乏与之相匹配的if语句。本错误的产生出了是因为else多于外,还或者是由于有剩余的分公司、漏泄大括号或前边的if语句出现语法错误而滋生。
78.         misplaced elif divective
elif地点错。编写翻译程序没有察觉与#elif指令相匹配的#if、#ifdef或#ifndef指令
79.         misplaced else directive
else地点错。编写翻译程序没有察觉与#else指令相匹配的#if、#ifdef或#ifndef指令
80.         misplaced enlif divective
endif地点错。编写翻译程序尚未意识与#endif指令相匹配的#if、#ifef或#ifndef指令
81.         must be addressable
务必是可编址的。取之操作符“&”成效于七个编址的对象,如寄存器变量。
82.         must take address of memory location
必须是内部存款和储蓄器一地址。源文件中对不可编址的表达式使用了地址操作符
83.         no file name ending
无文件名终止符。在#include语句中,文件名缺少科学的闭引号(”)或按括号(>)。
84.         no file names given
未提交文件名。Turbo命令编写翻译(TCC)中从不别的公文
85.         non-portable pointer assihnment xsw
对不可移植的指针赋值。原程序将几个指南针赋给1个非指针,或相反。但作为特例允许把常量零值赋给3个指南针,假如是那种景色,能够强行抑制本错误消息。
86.         non-portable pointer comparison
不足移植的指针相比较。源程序团长二个指针与1个非指针(常量零除外)举办相比。但借使相比较适当,则应强行抑制本错误消息。
87.         non-portable return type conversion
不行移植的归来类型转换。在回到语句中的表明式类型与函数表明中的类型不一致。但只要函数的回到表达式是一指南针,则足以开始展览更换,此时,再次回到指针的函数恐怕送回二个常量零,而零被转换来多少个体面的指针值。
88.         not an allowed type
不一致意的项目,在源文件中表达了两种禁止了的品种,如函数重临三个函数或数组。
89.         out of memory
内部存款和储蓄器不够。
90.         pointer required o left side of
操作符右边须是2个指针
91.         redeclaration of ‘xxxxxxx’
“xxxxxxx”重定义。
92.         size of structure or array not known
结构或数大小不定。有个别表达式(或如sizeof或存款和储蓄表明)中冒出了一个为定义的组织或一个空长度数组。假设社少将度不必要,则在概念从前就可援引;如若数组不报名存款和储蓄空间依然起始化是给定了长短。则可定义为空长。
93.         statement missing
语句紧缺“:”。
94.         structure or union symtax error
组织或联名语法错误。编写翻译程序意识在struct或union关键字背后没有标识符或大括号
95.         stucture size too large
布局太大。源文件中表明的布局所需的内部存款和储蓄器域太大学一年级直内部存款和储蓄器空间不够。
96.         subscripting missing]
下标缺乏“]”。大概是由于漏电或多写操作符或括号不匹配引起的。
97.         subscripting missing()
switch语句中缺点和失误“()”。
98.         too few paramenters in call
函数调用参数太少。对含蓄原型的函数调用(通过一个函数指针)参数太少。原型须要提交全部参数。
99.         too few paramenters in call to ‘xxxxxxxxx’
调用“xxxxxx”是参数太少。调用钦命的函数(该行数用一原型注脚)时,给出的参数太少。
100.         too many cases
case太多。switch语句最多允许有25多少个case。
101.         too many decimal points
十进制小数电太多。
102.         too many default cases
default太多。switch语句中不得不有三个default。
103.         too mandy wxponents
阶码太多。
104.         too many initializers
初阶化太多。
105.too many storage classes in declaration
证实中存储累太多。三个验证只同意有一种存款和储蓄类。
106.Too many types in declaration
表达中项目太多。一个证实只同意有一种下列基本类型:char,int,float,double,struct,union,enum,typedef名。
107.Too much auto memory in function
函数中自动储存太多。当前函数评释的活动储存抢先了可用的积存空间。
108.Too much code define   in file
文件定义的代码太多。当前文件中函数的总长度抢先了64k字节。可以移去不供给的代码或把源文件分别写下来。
109.Too much global data define in file
文件中定义的全局注脚的总额当先了64k字节。检查一下一些数组定义是还是不是太长。假如所需的证明是少不了的,则要
再也组织程序。
110.Two consecutive dots
三个延续点。因为省略号蕴涵三点(…),而是禁止小数点和挑选操作符使用了二个电(.),所以,再C程序中不相同意出现七个一而再点。
111.         type mismatch in parameter#
“#”参数类型不般配。通过3个指南针访问已由原型表明的参数时,给定参数#N(从左到右N各种加1)不能够转换为已证实的参数类型。
112.         type mismatch in parameter # in call to ‘xxxxxxx’
调用“xxxxxx”参数#品种不般配。源文件中经过二个原型中证实了点名的参数,而加以的参数(从左到右N各个加1)不能转换为已证实的参数类型。
113.         type mismatch in parameter ‘xxxxxx’
参数”yyyyyy”类型不包容。源文件中通过一个原型表达了可以有函数指针调用的函数,而所制定的参数不能够转化为另3个已表达的参数类型。
114.         type mismatch in parameter ‘xxxxxxx’ in call to
‘yyyyyyyy’
调用“xxxxxx”时,参数”xxxxxx”类型不包容。源文件中经过一个原型说明钦赐的参数。而所制定的参数不能转化为另2个已申明的参数类型。
115.         type mismatch in redeclaration of ‘xxx’
重定义类型不合营。源文件中把叁个已表达的变量来重新表达为另一种变量。假设三个函数被调用,而后又被申明成非整形也会生出本错误,在那种场所下,必须在首先次调用函数前,给函数加上extern表达。
116.         unable to create output file ‘xxxxxxxx’
无法创设输出文件“xxxxxxxx.xxx”。当工作软盘已瞒或有写尊敬时发出本错误。
117.         unable to create turboc.lnk
无法创造turboc.lnk。编写翻译程序不可能创立暂时文件TURBOC.$LN,因为不可能存取磁盘恐怕磁盘已瞒。
118.         unable to execute command ‘xxxxxxxx’
不能够执行“xxxxxx”命令。找不到TLINK或MASM,或许磁盘出错。
119.         unable to open include file ‘xxxxxxxx.xxx’
不可能打开蕴含文件“xxxxxx.xxx”。编译程序找不到该包罗文件。大概是出于二个#include文件包含它本人而引起的,也只怕是根目录下的CONFIG.SYS中并未安装能而且开辟的文件个数(试加一句file=2)。
120.         unable to open inputfile ‘xxxxxxx.xxx’
无法开拓输入文件“xxxxxx.xxx”。编写翻译程序找不到源文件时出现本错误。检查文件名是还是不是拼错,或检核对应的磁盘目录中是不是有此文件。
121.         undefied label ‘xxxxxx’
标明“xxxxxx”未定义。函数中goto语句后的标注没有概念。
122.         undefied structure ‘xxxxxx’
结构“xxxxxx”未定义。源文件中利用了未经证实的某部协会。或者是出于组织名拼写错或紧缺结构表明而引起的。
123.         undefied symbol ‘xxxxxx’
标志“xxxxxx”未定义。标识符无定义,可能是出于表达或引用有拼写错误,也或者是出于标识符表明错误而引起。
124.         unwxpected end of file in comment started on line #
源文件在某些注释中竟然截止。。平常是出于注释甘休标志“*/”漏掉引起。
125.         undefied end of file in conditional stated on line #
源文件在#行初阶的标准化语句中竟然甘休。在编译程序蒙受#endif前源程序甘休,经常是由于#endif漏掉或拼写错误引起。
126.         unknown preprocessor directire ‘xxx’
不认识的预处理指令:xxx。编写翻译程序在某含伊始碰着“#”字符,但此后的授命名不是下列之一:define,undef,line,ifdef,ifndef,include,else或endif.
127.         unteminated character constant
为竣事的字符常量。编写翻译程序意识一个不合作的省略符。
128.         unteminated string
为了却的串。编写翻译程序意识三个不协作的引号。
129.         unteminated string or character constant
为甘休的串或字符常量。编写翻译程序意识串或字符常量早先后不曾甘休。
130.         user break
用户中断,在合龙环境中实行编写翻译或连续是用户按了Ctrl+Break键。
131.         while statement missing()
while语句漏掉()
132.         wrong number of argument in‘xxxxxx’
调用“xxxxxx”时参数个数错误。源文件中调用有些宏时,参数个数不对。

2009-02-10 作者: infobillows 来源:网络

iconv_open”
iconv_open”

#define DOWNLOAD_IMAGE_LOG /var/log/png.log


在将三个C源程序转换为可执行程序的历程中, 编写翻译预处理是最初的步骤.
这一步骤是由预处理器(preprocessor)来成功的. 在源头程序被编写翻译器处理以前,
预处理器首先对源程序中的”宏(macro)”进行处理.

no iconv implementation, cannot convert from %s to %s”
没有 iconv 的实现,无法从 %s 转换到 %s”

#define WGET_IMAGE_(x) “wget -b -c -P ./media/video -a ” x ” -i
 mp4url.txt”

C初学者可能对预处理器没什么概念, 那是未可厚非的:
一般的C编写翻译器都将预处理, 汇编, 编写翻译, 连接进程集成到联合了.
编写翻译预处理往往在后台运转. 在某个C编写翻译器中,
那么些经过统统由三个单身的程序来形成, 编译的不等阶段落实那一个差异的成效.
能够钦赐相应的授命选项来实行这一个作用.
有的C编写翻译器使用各自的主次来形成那个步骤. 可独立调用这一个程序来完毕.
在gcc中, 举办编写翻译预处理的次第被号称CPP, 它的可执行文件名为cpp.

character 0x%lx is not in the basic source character set\n”
字符 0x%lx 不在基本源字符集中\n”

WGET_IMAGE_(DOWNLOAD_IMAGE_LOG)就是 wget -b -c -P ./media/video -a
/var/log/png.log -i  mp4url.txt 

编写翻译预处理命令的语法与C语言的语法是全然独立的. 比如:
你能够将三个宏扩张为与C语法格格不入的始末,
但该内容与背后的话语结合在2个若能生成合法的C语句, 也是足以正确编译的.

converting to execution character set”
更换来可执行文件的字符集”


(一) 预处理命令简介

character 0x%lx is not unibyte in execution character set”
字符 0x%lx 在履行字符集中不是单字节的”

 

预处理命令由#(hash字符)初阶, 它独占一行, #前面只可以是空荡荡符.
以#千帆竞发的口舌正是预处理命令, 不以#伊始的言辞为C中的代码行.
常用的预处理命令如下:

Character %x might not be NFKC”
字符 %x 大概不是 NFKC”

C、C++宏体中冒出的#,#@,##,

#define定义二个预处理宏

universal character names are only valid in C++ and C99″
Unicode 字符名只在 C++ 和 C99 中央银立见成效”


#undef废除宏的概念

the meaning of ‘\\%c’ is different in traditional C”
‘\\%c’的意思与在价值观 C 中区别”

1,  #表字符串化(stringfication),如 

#include包含文件命令

In _cpp_valid_ucn but not a UCN”
在 _cpp_valid_ucn 中但不是一个 UCN”

#define C(x) #x  

#include_next与#include相似, 但它装有尤其的用途

incomplete universal character name %.*s”
不完全的 Unicode 字符名 %.*s”

C(I am a string) —> “I am a string”

#if编写翻译预处理中的条件命令, 也正是C语法中的if语句

%.*gcc编写翻译错误表,C中的预编写翻译宏定义。s is not a valid universal character”
%.*s 不是三个灵光的 Unicode 字符”


#ifdef判断某个宏是或不是被定义, 若已定义, 执行随后的语句

‘$’ in identifier or number”
‘$’出现在标识符或数字中”

2, ##表字符串连接(concatenation)**

#ifndef与#ifdef相反, 判断有个别宏是还是不是未被定义

universal character %.*s is not valid in an identifier”
Unicode 字符 %.*s 在标识符中无效”

右侧的代码能够透过宏字符串连接来简化:

#elif若#if, #ifdef, #ifndef或前面包车型客车#elif条件不满意,
则执行#elif之后的言语, 也正是C语法中的else-if

universal character %.*s is not valid at the start of an identifier”
Unicode 字符 %.*s 在标识符先导无效”

如#define  cmd(x)  x ## _command

#else与#if, #ifdef, #ifndef对应, 若这么些标准不知足,
则执行#else之后的言语, 相当于C语法中的else

converting UCN to source character set”
将 UCN 转换来源字符集”

cmd(quit) 就是
quit_command

#endif#if, #ifdef, #ifndef那几个规则命令的终止标志.

converting UCN to execution character set”
将 UCN 转换成实施字符集”

实用的事例如下:

defined与#if, #elif同盟使用, 判断有个别宏是还是不是被定义

the meaning of ‘\\x’ is different in traditional C”
‘\\x’的含义与在守旧 C 中不相同”

struct command
{
    char *name;
    void (*function) (void);
};

struct command commands[] =
{
    { "quit", quit_command },
    { "help", help_command },
    ...
};

改成如下:

#define COMMAND(NAME)  { #NAME, NAME ## _command }

struct command commands[] =
{
    COMMAND (quit),
    COMMAND (help),
};

#line标志该语句所在的行号

\\x used with no following hex digits”
\\x 后没有 16 进制数字”

 

#将宏参数替代为以参数值为剧情的字符窜常量

hex escape sequence out of range”
16 进制转义体系越界”

上边包车型大巴代码应用宏字符串化来输出音信:

##将八个相邻的标志(token)连接为3个独门的标志

octal escape sequence out of range”
8 进制转义系列越界”

#define WARN_IF(expr)   do{ if(expr) {fprintf(stderr, "warning" #expr "\n");}}while(0)

#pragma表达编写翻译器新闻

the meaning of ‘\\a’ is different in traditional C”
‘\\a’的意思与在价值观 C 中区别”

利用do while的原故是为着让WA昂科威N_IF(expr)后边加分号使之看起来更像函数。

#warning展现编写翻译警告新闻

non-ISO-standard escape sequence, ‘\\%c’”
非 ISO 标准的转义类别,‘\\%c’”


#error突显编写翻译错误音讯

unknown escape sequence: ‘\\%c’”
不解的转义系列:‘\\%c’”

宏扩展

(二) 预处理的文法

unknown escape sequence: ‘\\%s’”
不解的转义体系:‘\\%s’”

预处理并不分析任何源代码文件, 它只是将源代码分割成一些标记(token),
识别语句中什么是C语句, 哪些是预处理语句. 预处理器能够辨识C标记, 文件名,
空白符, 文件结尾标志.

converting escape sequence to execution character set”
将转义系列转换成实施字符集”

#include <stdio.h>
#define str(s) #s
#define xstr(s) str(s)
#define foo 4
int main(int argc, char *argv[])
{
    printf ("%s\n",str(foo));
    printf ("%s\n",xstr(foo));
    return 0;
}

# 结果为foo 4

预处理语句格式:#command name(…) token(s)

character constant too long for its type”
字符常量大小超出其项目”

宏展开时先进行里层的宏,但含有#和##的宏不展开,由于str(foo)宏str包蕴#故foo不开始展览,而xstr宏中不带有#故foo展开为4,即str(4)再开展str得4

1, command预处理命令的名号, 它从前以#开头, #从此以往紧随预处理命令,
标准C允许#两边能够有空白符, 但比较老的编写翻译器恐怕不相同意那样.
若某行中只包罗#(以及空白符), 那么在标准C中该行被精晓为空白.
整个预处理语句之后只好有空白符大概注释, 无法有别的内容.

multi-character character constant”
多字节字符常量”


2, name代表宏名称, 它可带参数. 参数能够是可变参数列表(C99).

empty character constant”
空的字符常量”

同理可见上边结果为: _G(A,B) AB

3, 语句中得以选用”\”来换行.

failure to convert %s to %s”
无法从 %s 转换到 %s”

#define G(a,b) a##b
#define _G(a,b) G(a,b)
#define S(X) #X
#define _S(X) S(X)
#define A 1
#define B 2
#include<stdio.h>
int main()
{
    printf("%s\n",S(_G(A,B)));
    printf("%s\n",_S(G(A,B)));
    return 0;
}

e.g.

extra tokens at end of #%s directive”
#%s 提醒的末梢有剩余的标识符”

 

#  define  ONE 1 /* ONE == 1 */

#%s is a GCC extension”
#%s 是一个 GCC 扩展”


等价于:#define ONE 1

#%s is a deprecated GCC extension”
#%s 是1个已不合时宜的 GCC 扩张”

 

#define err(flag, msg) if(flag) \

suggest not using #elif in traditional C”
建议在古板 C 中不利用 #elif”

有关记号粘贴操作符(token paste operator): ##

printf(msg)

traditional C ignores #%s with the # indented”
当 # 有缩进时守旧 C 忽略 #%s”

1. 归纳的说,“##”是一种分隔连接格局,它的机能是先分隔,然后举办强制连接。

等价于:#define err(flag, msg) if(flag) printf(msg)

suggest hiding #%s from traditional C with an indented #”
提议选拔缩进的 # 以让 #%s 对传统 C 不可见”

   在那之中,分隔的成效类似于空格。我们知晓在平凡的宏定义中,预处理器一般把空格
   解释成分段标志,对于每一段和前面相比较,相同的就被沟通。不过如此做的结果是,
   被替换段之间存在一些空格。借使大家不希望出现这么些空格,就能够通过抬高级中学一年级些
   ##来顶替空格。

(三) 预处理命令详述

embedding a directive within macro arguments is not portable”
将一个指令嵌入宏参数中是不行移植的”

   别的一些相间标志是,包涵操作符,比如 +, -, *, /, [,], …,所以尽管上面包车型客车
   宏定义尚无空格,可是依旧表达有含义的概念: define add(a, b)  a+b

1, #define

style of line directive is a GCC extension”
line 提示的品格是二个 GCC 扩充”

   而其强制连接的功用是,去掉和前面包车型客车字符串之间的空格,而把互相连接起来。

#define命令定义3个宏:

invalid preprocessing directive #%s”
不行的预处理提醒 #%s”

2. 举列 – 试相比较下述多少个宏定义的区分

#define MACRO_NAME(args) tokens(opt)

\”defined\” cannot be used as a macro name”
“defined”不可能被用作宏名”

   #define A1(name, type)  type name_##type##_type 
   #define A2(name, type)  type name##_##type##_type

尔后现身的MACRO_NAME将被取而代之为所定义的符号(tokens). 宏可带参数,
而前边的号子也是可选的.

\”%s\” cannot be used as a macro name as it is an operator in C++”
“%s”不能够被视作宏名,因为它是 C++ 中的三个操作符”

   A1(a1, int);  /* 等价于: int name_int_type; */
   A2(a1, int);  /* 等价于: int a1_int_type;   */

对象宏

no macro name given in #%s directive”
#%s 提醒中未提交宏名”

   解释:
        1) 在首先个宏定义中,”name”和第②个”_”之间,以及第2个”_”和第三个
   ”type”之间平素不被分隔,所以预处理器会把name_##type##_type解释成3段:
   “name_”、“type”、以及“_type”,那在这之中惟有“type”是在宏前边出现过
    的,所以它能够被宏替换。

不带参数的宏被称为”对象宏(objectlike macro)”

macro names must be identifiers”
宏名必须是标识符”

        2) 而在其次个宏定义中,“name”和率先个“_”之间也被分隔了,所以
   预处理器会把name##_##type##_type解释成4段:“name”、“_”、“type”
   以及“_type”,这些中,就有多个能够被宏替换了。

#define日常用来定义常量, 此时的宏名称一般为题写的字符串.
那样便于修改那么些常量.

undefining \”%s\””
取消对“%s”的定义”

        3) A1和A2的概念也足以如下:
           #define A1(name, type)  type name_  ##type ##_type  
                                      <##前方随意添加有的空格>
           #define A2(name, type)  type name ##_ ##type ##_type

e.g.

missing terminating > character”
缺乏结尾的 > 字符”

    结果是## 会把前边的空格去掉达成强连接,获得和地点结果一致的宏定义

#define MAX 100

#%s expects \”FILENAME\” or ”
#%s 需要 \”FILENAME\” 或 ”

3. 任何有关 – 单独的三个 #

int a[MAX];

empty filename in #%s”
#%s 普通话件名为空”

   至于单独3个#,则意味着 对这些变量替换后,再加双引号引起来。比如

#ifndef __FILE_H__

#include nested too deeply”
#include 嵌套过深”

      #define  __stringify_1(x)   #x
那么
      __stringify_1(linux)   <==>  ”linux”

#define __FILE_H__

#include_next in primary source file”
#include_next 出现在主源文件中”

所以,对于MODULE_DEVICE_TABLE

#include “file.h”

invalid flag \”%s\” in line directive”
line 提醒中有不行的符号“%s””

     1) #define MODULE_DEVICE_TABLE(type,name)  
MODULE_GENERIC_TABLE(type##_device,name)

     2) #define MODULE_GENERIC_TABLE(gtype,name)      extern const struct gtype##_id __mod_##gtype##_table     
             __attribute__ ((unused, alias(__stringify(name))))

#endif

unexpected end of file after #line”
#line 后未料想的文本停止”

得到  
      MODULE_DEVICE_TABLE(usb, products)  
                             /*notes: struct usb_device_id products; */
 <==> MODULE_GENERIC_TABLE(usb_device,products)
 <==> extern const struct usb_device_id __mod_usb_device_table     
             __attribute__ ((unused, alias(”products”)))   

#define __FILE_H__ 中的宏就不带任何参数, 也不扩张为其它标记.
那常常用来包罗头文件.

\”%s\” after #line is not a positive integer”
#line 后的“%s”不是一个正整数”

只顾到alias attribute需求贰个双引号,所以在此地运用了__stringify(name)来
给name加上双引号。别的,还留意到三个外表变量”__mod_usb_device_table”被alias
到了本驱动专用的由用户自定义的变量products<usb_device_id类型>。这几个外部变量
是如何行使的,更加多的音讯请参考《probe()进度分析》。

要调用该宏, 只需在代码中钦定宏名称, 该宏将被取而代之为它被定义的内容.

line number out of range”
行号超出范围”


函数宏

\”%s\” is not a valid filename”
“%s”不是三个立见成效的公文名”

 

带参数的宏也被称为”函数宏”. 利用宏能够进步代码的运营作用:
子程序的调用必要压栈出栈, 这一经过借使过度频仍会消耗掉大批量的CPU运算能源.
所以一些代码量小但运营往往的代码如果使用带参数宏来达成会增强代码的运营功能.

\”%s\” after # is not a positive integer”
# 后的“%s”不是叁个正整数”

在标准C以及各中编写翻译器中定义了一部分对象宏, 那几个宏的名目以”__”初始和终极,
并且都以大写字符. 那个预订义宏可以被#undef, 也得以被重定义。

函数宏的参数是稳定的气象

invalid #%s directive”
无效的 #%s 指示”

      在ANSI
C标准中定义了__FILE__,__LINE__,__DATA__,__TIME__,__STDC__等专业的预订义宏。GCC对其进行扩充,也定义了三个约定义宏。

函数宏的概念选拔那样的章程: #define name( args ) tokens

registering pragmas in namespace \”%s\” with mismatched name
expansion”
在命名空间“%s”中登记 pragma 时名称扩大不包容”

      归纳起来GCC中可使用的预约义宏涵盖了如下几方面包车型地铁新闻:
     
壹 、宿主的音信:GNU的版本,编写翻译器的版本,类型的相干音信,字节序音讯等。
     
② 、编写翻译动作的消息:编写翻译的日子、时间;编写翻译时是或不是开始展览了时间或空中上的优化;定义的inline是否被编写翻译器执行等。
     
三 、文件的音讯:文件名称、函数名称、行数音讯、文件最后修改时间等等。
      肆 、计数音讯:__COUNTER__,__INCLUDE_LEVEL__等。

里面包车型地铁args和tokens都以可选的.
它和目的宏定义上的界别在于宏名称之后不带括号.

registering pragma \”%s\” with name expansion and no namespace”
pragma “%s”被登记为贰个命名扩张,而从不命名空间”

      上边是一对普遍的预约义宏的行使格局。

在意, name之后的左括号(必须紧跟name, 之间不可能有空格,
不然这就定义了贰个对象宏, 它将被替换为 以(初叶的字符串.
但在调用函数宏时, name与(之间能够有空格.

registering \”%s\” as both a pragma and a pragma namespace”
“%s”既被登记为二个pragma 又被注册为二个 pragma 命名空间”

1、__FILE__,__LINE__,FUNCTION__      
那是最常用到的预约义宏的重组,表示文件名、行数和函数名,用于程序运营期万分的跟踪。如:

e.g.

#pragma %s %s is already registered”
#pragma %s %s 已经被登记”

//——-file main.c———-
#include <stdio.h>
#include “myassert.h”

#define mul(x,y) ((x)*(y))

#pragma %s is already registered”
#pragma %s 已经被登记”

int func(const char *filename);

瞩目, 函数宏之后的参数要用括号括起来, 看看那几个例子:

registering pragma with NULL handler”
pragma 注册为被 NULL 处理”

int main(int argc,char **argv)
{
    MyAssert(“two args are needed”,argc==2);
    func(argv[1]);
    return 0;
}

e.g.

#pragma once in main file”
#pragma once 出现在主文件中”

//——-file func.c———-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include “myassert.h”

#define mul(x,y) x*y

invalid #pragma push_macro directive”
无效的 #pragma push_macro 指示”

int func(const char *filename)
{
    int fd;
    MyAssert(“filename can not be null”,filename);
    MyAssert(“file not exist”,0==access(filename,F_OK));
    fd = open(filename,O_RDONLY);
    close(fd);
    return 0;
}

“mul(1, 2+2);” 将被扩张为: 1*2 + 2

invalid #pragma pop_macro directive”
无效的 #pragma pop_macro 指示”

//——-file myassert.h———-
#ifndef __MY_ASSERT_H__
#define __美高梅手机版4858 ,MY_ASSERT_H__

如出一辙, 整个标记串也相应用括号引用起来:

invalid #pragma GCC poison directive”
无效的 #pragma GCC poison 指示”

#include <stdio.h>
#include <stdlib.h>

e.g.

poisoning existing macro \”%s\””
对已存在的宏“%s”投毒”

#define  MyAssert(message,assertion) do{/
    if(!(assertion)){/
        printf(“line %d in %s(%s)”, __LINE__,
__FILE__,__FUNCTION__);/
        if(message){/
            printf(” : %s”,message);/
        }/
        printf(“/n”);/
        abort();/
    }/
}while(0);
#endif

#define mul(x,y) (x)*(y)

#pragma system_header ignored outside include file”
#pragma system_heade 在蕴藏文件外被忽略”

#Makefile
TARGET = test
CC = gcc
CCFLAGS = -Wall
OBJS = main.o func.o

sizeof mul(1,2.0) 将被增添为 sizeof 1 * 2.0

cannot find source file %s”
找不到源文件 %s”

$(TARGET) : $(OBJS)
    $(CC) -o $@ $(OBJS) $(CCFLAGS)

调用函数宏时候, 传递给它的参数能够是函数的再次回到值,
也能够是别的有意义的话语:

current file is older than %s”
时下文件早于 %s”

%.o : %.c
    $(CC) -o $@ -c $< $(CCFLAGS)

e.g.

_Pragma takes a parenthesized string literal”
_Pragma 须求一个括起的字符串字面常量”

clean:
    rm -rf *.o 
    rm -rf $(TARGET)

mul (f(a,b), g(c,d));

#else without #if”
#else 没有匹配的 #if”

     
可知通过动用__FILE__,__LINE__,FUNCTION__宏,能够辅助大家准确的一定出现至极的文书、函数和行数。

e.g.

#else after #else”
#else 出现在 #else 后”

2、__BASE_FILE__

#define insert(stmt) stmt

the conditional began here”
规范自此初阶”

      这些宏是和__FILE__相对应的,表示主输入文件的名字,对于源文件而言__FILE__和__BASE_FILE__是同等的;对于头文件二者才也许两样。比如在上个例子中,__LINE__其一宏是在myassert.h文件中定义的,被main.c和func.c包涵之后__FILE__的值
分级成为了main.c和func.c。不过当大家期望知晓MyAssert那个宏具体实在哪些文件(实际上是myassert.h)中定义的话,就要求动用__BASE_FILE__。
     上边包车型客车事例能够辅助加深驾驭:

insert ( a=1; b=2;)  约等于在代码中进入 a=1; b=2 .

#elif without #if”
#elif 没有匹配的 #if”
#elif after #else”
#elif 出现在 #else 后”

 //——-file main.c———-
#include <stdio.h>
#include “basefile.h”

insert ( a=1, b=2;)  就有标题了: 预处理器会提醒出错:
函数宏的参数个数不匹配. 预处理器把”,”视为参数间的相间符.

#: directives.c:1960
#endif without #if”
#endif 没有匹配的 #if”

int main(int argc, char *argv[])
{
    printf(“%s/n”,sfile);
    printf(“%s/n”,hfile);
    return 0;
}

insert ((a=1, b=2;)) 可消除上述难题.

missing ‘(‘ after predicate”
谓词后紧缺‘(’”

//——-file basefile.h———-
const char sfile[]= __FILE__;
const char hfile[]= __BASE_FILE__;

在概念和调用函数宏时候, 要注意一些题材:

missing ‘)’ to complete answer”
全体的答案贫乏‘)’”

       gcc main.c &&./a.out 得到:

1, 大家平日用{}来引用函数宏被定义的内容,
那就要留意调用那么些函数宏时的”;”难题.

predicate’s answer is empty”
谓词的答案为空”

       basefile.h
       main.c

example_3.7:

assertion without predicate”
预感后不曾谓词”

 3、__DATE__,__TIME__        用于获取最终一遍编写翻译的日子和岁月(字符串格局):

#define swap(x,y) { unsigned long _temp=x; x=y; y=_tmp}

predicate must be an identifier”
谓词必须是四个标识符”

 

比方这么调用它: “swap(1,2);” 将被扩大为: { unsigned long _temp=1; 1=2;
2=_tmp};

\”%s\” re-asserted”
重断言“%s””

#include <stdio.h>
//——-file main.c———-
int main()
{
    printf(“DATE : %s/n”,__DATE__);
    printf(“TIME : %s/n”,__TIME__);
}

不问可知后边的;是剩下的, 大家相应那样调用: swap(1,2)

unterminated #%s”
未平息的 #%s”

 

即便如此的调用是合情合理的, 但它和C语法相悖,
可使用上边包车型客车措施来拍卖被{}括起来的剧情:

unterminated comment”
未甘休的注释”

       gcc main.c &&./a.out 得到:
       DATE : Jan 27 2011
       TIME : 17:12:55

#define swap(x,y) \

stdout”
stdout”

4、__TIMESTAMP__        和__TIME__的格式相同。同于获得本文件最后三次被修改的时日。

do { unsigned long _temp=x; x=y; y=_tmp} while (0)

%s: %s”
%s:%s”

5、__GNUC__、__GNUC_MINOR__、__GNUC_MINOR__、__GNUC_PATCHLEVEL__        用于获取GNU版本:

swap(1,2); 将被调换为:

too many decimal points in number”
数字中有太多小数点”

 

do { unsigned long _temp=1; 1=2; 2=_tmp} while (0);

fixed-point constants are a GCC extension”
固定常量是3个 GCC 扩大”

#include <stdio.h>
int main()
{
    if( __GNUC__ > 4 || 
        (__GNUC__ == 4 && (__GNUC_MINOR__ > 2 ||  
            (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ >
0)))){
        printf(“GNUC version is later than 3.3.2/n”);
    }else{
        printf(“GNUC version is older than 3.3.2/n”);
    }

在Linux内核源代码中对那种do-while(0)语句有那广泛的应用.

invalid digit \”%c\” in binary constant”
二进制常量中有不行数字“%c””

}

2, 有的函数宏是不可能用do-while(0)来落成的, 所以在调用时不能带上”;”,
最万幸调用后添加注释表明.

invalid digit \”%c\” in octal constant”
8 进制常量中有地下字符“%c””

 

eg_3.8:

invalid prefix \”0b\” for floating constant”
浮点常量的“0b”前缀无效”

 

#define incr(v, low, high) \

use of C99 hexadecimal floating constant”
利用 C99 式的 16 进制浮点常量”

6、__VERSION__      用于获取编写翻译器的本子      

for ((v) = (low),; (v) <= (high); (v)++)

exponent has no digits”
指数部分从没数字”

 

只可以以如此的形式被调用: incr(a, 1, 10)  /* increase a form 1 to 10 */

hexadecimal floating constants require an exponent”
16 进制浮点常量要求指数部分”

//——-file main.c———-
#include <stdio.h>
int main()
{
    printf(“Version : %s/n”,__VERSION__);
    return 0;
}

函数宏中的参数包蕴可变参数列表的情形

invalid suffix \”%.*s\” on floating constant”
浮点常量的“%.*s”后缀无效”

 

C99标准中新增了可变参数列表的内容. 不光是函数,
函数宏中也足以动用可变参数列表.

traditional C rejects the \”%.*s\” suffix”
传统 C 不接受“%.*s”后缀”

      gcc main.c && ./a.out得到:

#define name(args, …) tokens

suffix for double constant is a GCC extension”
双精度常量后缀是2个 GCC 扩张”

      Version : 4.1.2 (Gentoo 4.1.2 p1.0.2)
      能够和gcc -v互相印证

#define name(…) tokens

invalid suffix \”%.*s\” with hexadecimal floating constant”
十六进制浮点常量的“%.*s”后缀无效”

 

“…”代表可变参数列表, 假使它不是仅部分参数,
那么它只好出现在参数列表的最后. 调用这样的函数宏时,
传递给它的参数个数要不少于参数列表中参数的个数(多余的参数被抛弃).

decimal float constants are a GCC extension”
十进制浮点常量是三个 GCC 扩大”

7、__COUNTER__
     
自个儿计数器,用于记录此前编写翻译进度中冒出的__COUNTER__的次数,从0起先计数。常用于组织一文山会海的变量名称,函数名称等。如:
//——-file main.c———-
#include <stdio.h>

通过__VA_ARGS__来替换函数宏中的可变参数列表.
注意__VA_ARGS__只得用于函数宏中参数中包涵有”…”的景况.

invalid suffix \”%.*s\” on integer constant”
平头常量的“%.*s”后缀无效”

#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)  
#define FUNC(x) FUNC1(x,__COUNTER__)

e.g.

use of C++0x long long integer constant”
运用 C++0x long long 整数常量”

int FUNC(var);
int FUNC(var);

#ifdef DEBUG

imaginary constants are a GCC extension”
虚数常量是二个 GCC 扩大”

int main() {
    var0 = 0;
    var1 = 1;
    printf(“%d/n”,var0);
    printf(“%d/n”,var1);
    return 0;
}
      gcc main.c &&a.out获得结果:
      0
      1
      那里运用__COUNTER__布局了七个变量:var0,var1。

#define my_printf(…) fprintf(stderr, __VA_ARGS__)

binary constants are a GCC extension”
二进制常量是一个 GCC 扩张”

8、__INCLUDE_LEVEL__
     
用于表示文件被含有的计数,从0起始递增,常作为递归包括的限制标准。如:

#else

integer constant is too large for its type”
平头常量值超出其连串”

 
//——-file main.c———-
#include <stdio.h>
int main()
{
   #define REP_LIMIT 10
   #define REP(BLAH) printf(“%d “, BLAH);
   #include “rep.h”
   printf(“/n”);
   return 0;
}

#define my_printf(…) printf(__VA_ARGS__)

integer constant is so large that it is unsigned”
平头常量太大,认定为 unsigned”

//——–file rep.h———-
#if __INCLUDE_LEVEL__ < REP_LIMIT
REP(__INCLUDE_LEVEL__)
#include “rep.h”
#endif

#endif

missing ‘)’ after \”defined\””
“defined” 后出现‘)’”

      gcc main.c && ./a.out,得到结果:
      1 2 3 4 5 6 7 8 9
      在那么些事例汉语件rep.h自包蕴了7回,执行了七遍REP(BLAH)。

tokens中的__VA_ARGS__被替换为函数宏定义中的”…”可变参数列表.

operator \”defined\” requires an identifier”
操作符“defined”供给二个标识符”

      实际上,__INCLUDE_LEVEL__最多的是和#include
__FILE__构成使用,用于表示3个递归。如:

注目的在于使用#define时候的有的普遍错误:

(\”%s\” is an alternative token for \”%s\” in C++)”
(在 C++ 中“%s”会是“%s”的替代标识符)”

 //——-file main.c———-
#ifndef AUTOINC
#define AUTOINC

#define MAX = 100

this use of \”defined\” may not be portable”
选择“defined”也许不便于移植”

#include <stdio.h>
#define MAX_LEVEL 10
int main()
{
    int i = 0;
    #include __FILE__
    printf(“/n”);
    return 0;
}
#undef AUTOINC
#endif

#define MAX 100;

floating constant in preprocessor expression”
浮点常量出现在预处理表明式中”

#ifdef AUTOINC
    #if __INCLUDE_LEVEL__ <= MAX_LEVEL
    printf(“%d “,__INCLUDE_LEVEL__);
    #include __FILE__

=, ; 的施用要值得注意. 再不怕调用函数宏是要注意, 不要多付出”;”.

imaginary number in preprocessor expression”
预处理表明式中出现虚数”

    #if __INCLUDE_LEVEL__ != MAX_LEVEL
    printf(“%d “,__INCLUDE_LEVEL__);
    #endif

小心: 函数宏对参数类型是不灵敏的, 你不用考虑将何种数据类型传递给宏.
那么, 怎样营造对参数类型敏感的宏呢? 参考本章的第⑨片段,
关于”##”的介绍.

\”%s\” is not defined”
“%s”未定义”

    #endif
#endif
      gcc main.c && ./a.out获得结果:
      1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1

有关定义宏的别的一些标题

assertions are a GCC extension”
预感是3个 GCC 增添”

 

(1) 宏可以被反复定义, 前提是那么些概念必须是一样的.
这里的”相同”必要先后定义中空白符出现的职位相同,
但具体的空白符类型或数额可不等,
比如原先的空格可替换为多个别的连串的空白符: 可为tab, 注释…

assertions are a deprecated extension”
预见是2个已不合时宜的 GCC 增添”

ANSI C标准中有多少个正规预约义宏:

e.g.

missing binary operator before token \”%s\””
标识符“%s”前缺乏二元运算符”

__FILE__     __DATE__   __TIME___    __LINE__   等

#define NULL 0

token \”%s\” is not valid in preprocessor expressions”
标识符“%s”在预处理表明式中没用”

__LINE__:在源代码中插入当前源代码行号;

#define NULL /* null pointer */     0

missing expression between ‘(‘ and ‘)’”
‘(’与‘)’之间缺少表明式”

__FILE__:在源文件中插入当前源文件名;

下边包车型客车重定义是同一的, 但上边包车型客车重定义分歧:

%s with no expression”
%s 后没有表明式”

__DATE__:在源文件中插入当前的编写翻译日期

#define fun(x) x+1

operator ‘%s’ has no right operand”
操作符‘%s’没有右操作数”

__TIME__:在源文件中插入当前编写翻译时间;

#define fun(x) x + 1 或: #define fun(y) y+1

operator ‘%s’ has no left operand”
操作符‘%s’没有左操作数”

__STDC__:当供给程序严酷遵从ANSI C标准时该标识被赋值为1;

设若反复概念时, 再度定义的宏内容是例外的, gcc会给出”NAME
redefined”警告音信.

‘:’ without preceding ‘?’”
‘:’前没有‘?’”

__cplusplus:当编辑C++程序时该标识符被定义。

有道是防止双重定义函数宏, 不管是在预处理命令中仍然C语句中,
最好对有个别对象唯有十足的定义. 在gcc中, 若宏现身了重定义, gcc会给出警告.

unbalanced stack in %s”
%s 中堆栈不平衡”

 

(2) 在gcc中, 可在指令行中钦命对象宏的概念:

impossible operator ‘%u’”
一点都不大概的操作‘%u’”

 

e.g.

missing ‘)’ in expression”
表明式中缺点和失误‘)’”

 

$gcc -Wall -DMAX=100 -o tmp tmp.c

‘?’ without following ‘:’”
‘?’后没有‘:’”

一 、标准预订义宏
The standard predefined macros are specified by the relevant language
standards, so they are available with all compilers that implement those
standards. Older compilers may not provide all of them. Their names all
start with double underscores.

一定于在tmp.c中添加” #define MAX 100″.

integer overflow in preprocessor expression”
预处理表明式中整数溢出”

__FILE__
This macro expands to the name of the current input file, in the form of
a C string constant. This is the path by which the preprocessor opened
the file, not the short name specified in #include or as the input file
name argument. For example, “/usr/local/include/myheader.h” is a
possible expansion of this macro.

那么, 假若原先tmp.c中包蕴MAX宏的概念, 那么再在gcc调用命令中应用-DMAX,
会出现什么样状态吧?

missing ‘(‘ in expression”
表达式中缺乏‘(’”

__LINE__
This macro expands to the current input line number, in the form of a
decimal integer constant. While we call it a predefined macro, it’s a
pretty strange macro, since its “definition” changes with each new line
of source code.
__FILE__ and __LINE__ are useful in generating an error message
to report an inconsistency detected by the program; the message can
state the source line at which the inconsistency was detected. For
example,

—若-DMAX=1, 则正确编写翻译.

the left operand of \”%s\” changes sign when promoted”
“%s”的左操作数在晋级时变换了标记”

     fprintf (stderr, “Internal error: “
                      “negative string length “
                      “%d at %s, line %d.”,
              length, __FILE__, __LINE__);
    
An #include directive changes the expansions of __FILE__ and
__LINE__ to correspond to the included file. At the end of that
file, when processing resumes on the input file that contained the
#include directive, the expansions of __FILE__ and __LINE__
revert to the values they had before the #include (but __LINE__ is
then incremented by one as processing moves to the line after the
#include).

—若-DMAX的值被内定为不为1的值, 那么gcc会给出MAX宏被重定义的警戒,
MAX的值仍为1.

the right operand of \”%s\” changes sign when promoted”
“%s”的右操作数在升级时变换了符号”

A #line directive changes __LINE__, and may change __FILE__ as
well. See Line Control.

小心: 若在调用gcc的命令行中不出示地付出对象宏的值,
那么gcc赋予该宏暗中认可值(1), 如: -DVAL == -DVAL=1

traditional C rejects the unary plus operator”
历史观 C 不收受单目 + 运算符”

C99 introduces __func__, and GCC has provided __FUNCTION__ for a
long time. Both of these are strings containing the name of the current
function (there are slight semantic differences; see the GCC manual).
Neither of them is a macro; the preprocessor does not know the name of
the current function. They tend to be useful in conjunction with
__FILE__ and __LINE__, though.

(3) #define所定义的宏的功效域

comma operator in operand of #if”
#if 操作数中冒出逗号”

__DATE__
This macro expands to a string constant that describes the date on which
the preprocessor is being run. The string constant contains eleven
characters and looks like “Feb 12 1996”. If the day of the month is less
than 10, it is padded with a space on the left.
If GCC cannot determine the current date, it will emit a warning message
(once per compilation) and __DATE__ will expand to “??? ?? ????”.

宏在定义之后才生效, 若宏定义被#undef取消, 则#undef之后该宏无效.
并且字符串中的宏不会被识别

division by zero in #if”
#if 中用零做除数”

__TIME__
This macro expands to a string constant that describes the time at which
the preprocessor is being run. The string constant contains eight
characters and looks like “23:59:01”.
If GCC cannot determine the current time, it will emit a warning message
(once per compilation) and __TIME__ will expand to “??:??:??”.

e.g.

NULL directory in find_file”
find_file 中有 NULL 目录”

__STDC__
In normal operation, this macro expands to the constant 1, to signify
that this compiler conforms to ISO Standard C. If GNU CPP is used with a
compiler other than GCC, this is not necessarily true; however, the
preprocessor always conforms to the standard unless the -traditional-cpp
option is used.
This macro is not defined if the -traditional-cpp option is used.

#define ONE 1

one or more PCH files were found, but they were invalid”
找到三个或四个 PCH 文件,但它们是船到江心补漏迟的”

On some hosts, the system compiler uses a different convention, where
__STDC__ is normally 0, but is 1 if the user specifies strict
conformance to the C Standard. CPP follows the host convention when
processing system header files, but when processing user files
__STDC__ is always 1. This has been reported to cause problems; for
instance, some versions of Solaris provide X Windows headers that expect
__STDC__ to be either undefined or 1. See Invocation.

sum = ONE + TWO    /* sum = 1 + TWO  */

use -Winvalid-pch for more information”
动用 -Winvalid-pch 以博取越来越多新闻”

__STDC_VERSION__
This macro expands to the C Standard’s version number, a long integer
constant of the form yyyymmL where yyyy and mm are the year and month of
the Standard version. This signifies which version of the C Standard the
compiler conforms to. Like __STDC__, this is not necessarily
accurate for the entire implementation, unless GNU CPP is being used
with GCC.
The value 199409L signifies the 1989 C standard as amended in 1994,
which is the current default; the value 199901L signifies the 1999
revision of the C standard. Support for the 1999 revision is not yet
complete.

#define TWO 2

%s is a block device”
%s 是3个块设备”

This macro is not defined if the -traditional-cpp option is used, nor
when compiling C++ or Objective-C.

sum = ONE + TWO    /* sum = 1 + 2    */

%s is too large”
%s 过大”

__STDC_HOSTED__
This macro is defined, with value 1, if the compiler’s target is a
hosted environment. A hosted environment has the complete facilities of
the standard C library available.

#undef ONE

%s is shorter than expected”
%s 短于预期”

__cplusplus
This macro is defined when the C++ compiler is in use. You can use
__cplusplus to test whether a header is compiled by a C compiler or a
C++ compiler. This macro is similar to __STDC_VERSION__, in that it
expands to a version number. A fully conforming implementation of the
1998 C++ standard will define this macro to 199711L. The GNU C++
compiler is not yet fully conforming, so it uses 1 instead. We hope to
complete our implementation in the near future.

sum = ONE + TWO    /* sum = ONE + 2  */

no include path in which to search for %s”
并未包括路径可供搜索 %s”

__OBJC__
This macro is defined, with value 1, when the Objective-C compiler is in
use. You can use __OBJC__ to test whether a header is compiled by a
C compiler or a Objective-C compiler.

char c[] = “TWO”   /* c[] = “TWO”, NOT “2”! */

Multiple include guards may be useful for:\n”
多个制止重包括或许对其有用:\n”

__ASSEMBLER__
This macro is defined with value 1 when preprocessing assembly language.

(4) 宏的替换能够是递归的, 所以能够嵌套定义宏.

cppchar_t must be an unsigned type”
cppchar_t 必须是无符号型”

 

e.g.

preprocessor arithmetic has maximum precision of %lu bits; target
requires %lu bits”
预处清理计算术的万丈精度为 %lu 位;指标须求 %lu 位”

__DATE__ 举办预处理的日期(“Mmm dd yyyy”格局的字符串文字,如May 27
二零零六)
__FILE__ 代表当前源代码文件名的字符串文字
,包涵了详实路径,如G:/program/study/c+/test1.c
__LINE__ 代表当前源代码中的行号的平头常量
__TIME__ 源文件编译时间,格式微“hh:mm:ss”,如:09:11:10;
__func__ 当前所在函数名,在编写翻译器的较高版本中扶助
__FUNCTION__ 当前所在函数名

# define ONE NUMBER_1

CPP arithmetic must be at least as precise as a target int”
CPP 算术必须至少存有指标 int 的精度”

  对于__FILE__,__LINE__,__func__,__FUNCTION__
那样的宏,在调试程序时是很有用的,因为你能够很不难的接头程序运转到了哪个文件的那一行,是哪个函数。
而对于__DATE__,__TIME__则能够收获编写翻译时间,如如下代码通过宏获取编写翻译时间,并因此sscanf()从中获得具体的年月日时分秒数据,可在代码中做相应采用。笔者的代码中是基于此数据作为版本标识,并依此判断哪些版本新些及是不是供给升级。
char * creationDate   = __DATE__ “, ” __TIME__;
sscanf(creationDate, “%s %d %d, %d:%d:%d”, month, &day, &year, &hour,
&min, &sec);

# define NUMBER_1 1

target char is less than 8 bits wide”
目标 char 短于 8 位”

预处理命令#pragma和预定义宏–转发

一、C预订义宏
C标准钦命了部分约定义宏,编制程序中常常用到。
__DATE__     进行预处理的日子
__FILE__     代表当前源代码文件名的字符串
__LINE__     代表当前源代码文件中央银行号的整数常量
__STDC__     设置为1时,表示该兑现遵从C标准
__STDC_HOSTED__  为本机环境设置为,不然设为0
__STDC_VERSION__ 为C99时设置为壹玖玖陆01L
__TIME__     源文件的编写翻译时间
__func__     C99提供的,为所在函数名的字符串
对于__FILE__,__LINE__,__func__那样的宏,在调节和测试程序时是很有用的,因为您能够很不难的了解程序运维到了哪些文件的那一行,是哪个函数.

例如:
#include
#include
void why_me();
int main()
{
    printf( “The file is %s/n”, __FILE__ );
    printf( “The date is %s/n”, __DATE__ );
    printf( “The time is %s/n”, __TIME__ );
    printf(“The version is %s/n”,__STDC__VERSION__);
    printf( “This is line %d/n”, __LINE__ );
    printf( “This function is %s/n “, __func__ );
   why_me();
   return 0;
}
void why_me()
{
    printf( “This function is %s/n”, __func__ );
    printf( “This is line %d/n”, __LINE__ );
}

二、#line和#error
#line用于重置由__LINE__和__FILE__宏内定的行号和文件名。
用法如下:#line number filename
例如:#line 1000 //将当前行号设置为一千
     #line 一千 “lukas.c”   //行号设置为一千,文件名设置为lukas.c

#error指令使预处理器发出一条错误消息,该新闻包括指令中的文本.那条指令的指标就是在程序崩溃此前能够交给一定的消息。

三、#pragma 在拥有的预处理指令中,#Pragma
指令大概是最复杂的了。#pragma的成效是设定编写翻译器的情事只怕是指示编写翻译器实现都部队分特定的动作。#pragma指令对种种编写翻译器给出了二个主意,在维持与C和C++语言完全协作的场所下,给出主机或操作系统专有的特色。依照定义,编译提醒是机械或操作系统专有的,且对于各种编写翻译器都以分化的。
其格式一般为: #Pragma Para
其间Para 为参数,上边来看一些常用的参数。

(1)message 参数。 Message
参数是自身最欣赏的一个参数,它亦可在编写翻译信息输出窗口中输出相应的音信,那对于源代码消息的决定是老大重庆大学的。其选取方法为:
#Pragma message(“音信文本”)
当编写翻译器遇到那条指令时就在编写翻译输出窗口准将音信文本打字与印刷出来。
当大家在先后中定义了重重宏来控制源代码版本的时候,大家本人有或许都会遗忘有没有不易的装置那几个宏,此时大家能够用那条指令在编写翻译的时候就进展检查。借使大家希望判断自个儿有没有在源代码的怎么着地方定义了_X86这几个宏能够用下边包车型大巴格局
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
当我们定义了_X86那一个宏以往,应用程序在编写翻译时就会在编写翻译输出窗口里显示“_
X86 macro
activated!”。我们就不会因为不记得自个儿定义的一对特定的宏而顿足搓手了。

(2)另一个行使得相比多的pragma参数是code_seg。格式如:
#pragma code_seg( [“section-name”[,”section-class”] ] )
它能够设置程序中等高校函授数代码存放的代码段,当大家付出驱动程序的时候就会选拔到它。

(3)#pragma once (相比较常用)
假如在头文件的最起初投入这条指令就可见确认保证头文件被编写翻译二回。这条指令实际上在VC6中就早已有了,可是考虑到包容性并没有太多的使用它。

(4)#pragma
hdrstop表示预编写翻译头文件到此结束,后边的头文件不举行预编写翻译。BCB能够预编写翻译头文件以加速链接的速度,但如若具有头文件都进展预编写翻译又也许占太多磁盘空间,所以选择那几个选项排除部分头文件。
奇迹单元之间有依靠关系,比如单元A正视单元B,所以单元B要先于单元A编写翻译。你能够用#pragma
startup钦定编写翻译优先级,假设利用了#pragma package(smart_init)
,BCB就会依据优先级的大大小小顺序编写翻译。

(5)#pragma resource
“*.dfm”表示把*.dfm文件中的能源投入工程。*.dfm中总结窗体外观的定义。

(6)#pragma warning( disable : 4507 34; once : 4385; error : 164
)等价于:
#pragma warning(disable:4507 34) /*
不展现4507和34号警告音讯。假如编译时总是出现4507号警告和34号警告,
                                    而以为肯定不会有错误,可以运用那条指令。*/
#pragma warning(once:4385) // 4385号警告音讯仅报告三遍
#pragma warning(error:164) // 把164号警告音信作为一个不当。
再便是那个pragma warning 也协理如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
那里n代表三个警告等级(1—4)。
#pragma warning( push )保存全部警告音讯的水保的警示状态。
#pragma warning( push,
n)保存全体警告新闻的依存的警示状态,并且把全局警告等级设定为n。
#pragma warning( pop
)向栈中弹出最后一个警示音信,在入栈和出栈之间所作的任何改动撤销。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//…….
#pragma warning( pop )
在那段代码的末尾,重新保存全体的警告音信(包蕴4705,4706和4707)。

(7)pragma comment(…)
该指令将一个注脚记录放入一个对象文件或可执行文件中。
常用的lib关键字,能够帮大家连入3个库文件。 
(8)progma pack(n)
    钦赐结构体对齐方式!#pragma pack(n)来设定变量以n字节对齐方式。n
字节对齐正是说变量存放的起始地址的偏移量有三种情状:第一 、如若n大于等于该变量所占有的字节数,那么偏移量必须满意默许的对齐方式,第二 、若是n小于该变量的档次所占用的字节数,那么偏移量为n的翻番,不用满足暗中同意的对齐格局。结构的总大小也有个约束规范,分上边二种情况:要是n大于全数成员变量类型所占有的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的翻番; 不然必须为n的倍数。上面举例表达其用法。

#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4字节对齐
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//复苏对齐状态
为测试该意义,能够选用sizeof()测试结构体的长短!

 

在你写dll的时候,因为对此C和C++,编写翻译器会有例外的名字解析规则,所以能够那样用

#ifndef   __STDC__

extern “C ”   void   function();

#else

void   function();

#endif

 

 __LINE__           在源代码中插入当前源代码行号
  __FILE__           在源代码中插入当前源代码文件名
  __DATE__          
在源代码中插入当前编译日期〔注意和脚下系统日期差别开来〕
  __TIME__          
在源代码中插入当前编写翻译时间〔注意和当下系统时间分别开来〕  
  __STDC__          

int a = ONE  /* a = 1 */

target wchar_t is narrower than target char”
目录 wchar_t 短于目标 char”

当供给程序严俊服从ANSIC标准时该标识符被赋值为1。

标识符__LINE__和__FILE__常备用来调试程序;标识符__DATE__和__TIME__见惯司空用来在编译后的次序中到场三个时刻标志,以界别程序的不一致版本;当供给程序严谨遵守ANSIC标准时,标识符__STDC__就会被赋值为1;当用C++编译程序编写翻译时,标识符__cplusplus就会被定义。

#include

 

int main ()

{

    printf(“该输出游在源程序中的地方:%d/n”, __LINE__ );

    printf(“该程序的文书名为:%s/n”, __FILE__ );

    printf(“当今天子为:%s/n”, __DATE__ );

    printf(“当前时间为:%s/n”, __TIME__ );

 

    return 0;

}

#include

void main(void)

{

    printf(“%d”,__LINE__); // Line 5

}

结果为:5

 

// 标准预订义宏宏.cpp : Defines the entry point for the console
application.
//

#include “stdafx.h”

#include

void main(void)

{
 
    printf(“%d”,__LINE__); // Line 5
 

 

}

 

 

编译器宏使用总结
 
 
 

C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境。本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。ANSI标准定义的C语言预处理程序包括下列命令:

 

#define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。

 

命令#define定义了一个标识符及一个串。在源程序中每次遇到该标识符时,均以定义的串代换它。ANSI标准将标识符定义为宏名,将替换过程称为宏替换。命令的一般形式为:

 

#define identifier string

 

注意:

? 该语句没有分号。在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。

? 宏名定义后,即可成为其它宏名定义中的一部分。

? 宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。例如:

#define XYZ this is a tes

使用宏printf("XYZ");//该段不打印"this is a test"而打印"XYZ"。因为预编译器识别出的是"XYZ"

? 如果串长于一行,可以在该行末尾用一反斜杠’ /’续行。

 

处理器命令#error强迫编译程序停止编译,主要用于程序调试。

 

#include 命令#i nclude使编译程序将另一源文件嵌入带有#i nclude的源文件,被读入的源文件必须用双引号或尖括号括起来。例如:

 

#i nclude"stdio.h"或者#i nclude

 

这两行代码均使用C编译程序读入并编译用于处理磁盘文件库的子程序。

将文件嵌入#i nclude命令中的文件内是可行的,这种方式称为嵌套的嵌入文件,嵌套层次依赖于具体实现。

 

如果显式路径名为文件标识符的一部分,则仅在哪些子目录中搜索被嵌入文件。否则,如果文件名用双引号括起来,则首先检索当前工作目录。如果未发现文件,则在命令行中说明的所有目录中搜索。如果仍未发现文件,则搜索实现时定义的标准目录。

 

如果没有显式路径名且文件名被尖括号括起来,则首先在编译命令行中的目录内检索

 

如果文件没找到,则检索标准目录,不检索当前工作目录。

 

条件编译命令

有几个命令可对程序源代码的各部分有选择地进行编译,该过程称为条件编译。商业软件公司广泛应用条件编译来提供和维护某一程序的许多顾客版本。

 

#if、#else,#elif及#endif

 

#if的一般含义是如果#if后面的常量表达式为true,则编译它与#endif之间的代码,否则跳过这些代码。命令#endif标识一个#if块的结束。

 

#if constant-expression

statement sequence

#endif

 

跟在#if后面的表达式在编译时求值,因此它必须仅含常量及已定义过的标识符,不可使用变量。表达式不许含有操作符sizeof(sizeof也是编译时求值)。

 

#else命令的功能有点象C语言中的else;#else建立另一选择(在#if失败的情况下)。注意,# else属于# if块。

 

#elif命令意义与ELSE IF 相同,它形成一个if else-if阶梯状语句,可进行多种编译选择。#elif 后跟一个常量表达式。如果表达式为true,则编译其后的代码块,不对其它#elif表达式进行测试。否则,顺序测试下一块。

 

#if expression

statement sequence

#elif expression1

statement sequence

#endif

 

在嵌套的条件编译中#endif、#else或#elif与最近#if或#elif匹配。

 

# ifdef 和# ifndef

 

条件编译的另一种方法是用#ifdef与#ifndef命令,它们分别表示"如果有定义"及"如果无定义"。# ifdef的一般形式是:

 

# ifdef macroname

statement sequence

#endif

 

#ifdef与#ifndef可以用于#if、#else,#elif语句中,但必须与一个#endif。

 

命令#undef 取消其后那个前面已定义过有宏名定义。一般形式为:

#undef macroname

 

命令# line改变__LINE__与__FILE__的内容,它们是在编译程序中预先定义的标识符。命令的基本形式如下:

 

# line number["filename"]

 

其中的数字为任何正整数,可选的文件名为任意有效文件标识符。行号为源程序中当前行号,文件名为源文件的名字。命令# line主要用于调试及其它特殊应用。注意:在#line后面的数字标识从下一行开始的数字标识。

 

预定义的宏名

 

ANSI标准说明了C中的五个预定义的宏名。它们是:

 

__LINE__

__FILE__

__DATE__

__TIME__

__STDC__

 

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。

 

__LINE__及__FILE__宏指令在有关# line的部分中已讨论,这里讨论其余的宏名。

__DATE__宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。

源代码翻译到目标代码的时间作为串包含在__TIME__中。串形式为时:分:秒。

如果实现是标准的,则宏__STDC__含有十进制常量1。如果它含有任何其它数,则实现是非标准的。编译C++程序时,编译器自动定义了一个预处理名字__cplusplus,而编译标准C时,自动定义名字__STDC__。

 

注意:宏名的书写由标识符与两边各二条下划线构成。 

2, #undef

target int is narrower than target char”
对象 int 短于目的 char”

#undef用来撤销宏定义, 它与#define对立:

CPP half-integer narrower than CPP character”
CPP 半整数短于 CPP 字符”

#undef name

CPP on this host cannot handle wide character constants over %lu bits,
but the target requires %lu bits”
在此宿主机上,CPP 无法处理长于 %lu 位的宽字符常量,但指标需求 %lu 位”

如够被收回的宏实际上没有被#define所定义, 针对它的#undef并不会发生错误.

backslash and newline separated by space”
反斜杠和换行为空格所相隔”

当三个宏定义被收回后, 能够重新定义它.

backslash-newline at end of file”
反斜杠续行出现在文件末尾”

3, #if, #elif, #else, #endif

trigraph ??%c converted to %c”
三元符 ??%c 转换为 %c”

#if, #elif, #else, #endif用于规范编译:

trigraph ??%c ignored, use -trigraphs to enable”
三元符 ??%c 被忽略,请使用 -trigraphs 来启用”

#if 常量表明式1

\”/*\” within comment”
“/*”出以往诠释中”

语句…

%s in preprocessing directive”
预处理提醒中冒出 %s”

#elif 常量表明式2

null character(s) ignored”
忽略空字符”

语句…

`%.*s’ is not in NFKC”
‘%.*s’不在 NFKC 中”

#elif 常量表明式3

`%.*s’ is not in NFC”
‘%.*s’不在 NFC 中”

语句…

attempt to use poisoned \”%s\””
准备动用有剧毒的“%s””

__VA_ARGS__ can only appear in the expansion of a C99 variadic
macro”
__VA_ARGS__ 只好冒出在 C99 可变参数宏的拓展中”

#else

identifier \”%s\” is a special operator name in C++”
标识符“%s”是 C++ 中的3个特殊操作符”

语句…

raw string delimiter longer than 16 characters”
原始字符串分隔符长过 16 个字符”

#endif

invalid character ‘%c’ in raw string delimiter”
原始字符串分隔符中有不行字符‘%c’”

#if和#else分别也正是C语句中的if, else.
它们依照常量表明式的值来辨别是否实行后边的语句.
#elif也正是C中的else-if.
使用这个原则编写翻译命令能够方便地促成对源代码内容的控制.

unterminated raw string”
未甘休的原始字符串”

else之后不带常量表达式, 但若包蕴了常量表明式, gcc只是提交通警察告消息.

null character(s) preserved in literal”
空字符将保留在字面字符串中”

利用它们能够升官代码的可移植性—针对差异的平台运用进行不一的语句.
也不时用来大段代码注释.

missing terminating %c character”
缺乏结尾的 %c 字符”

e.g.

C++ style comments are not allowed in ISO C90″
C++ 风格的诠释在 ISO C90 中不被允许”

#if 0

(this will be reported only once per input file)”
(此警告为种种输入文件只报告三回)”

{

multi-line comment”
多行注释”

一大段代码;

unspellable token %s”
不恐怕拼出的标识符 %s”

}

macro \”%s\” is not used”
宏“%s”未被选用”

#endif

invalid built-in macro \”%s\””
不行的内建宏“%s””

常量表明式能够是带有宏, 算术运算, 逻辑运算等等的官方C常量表明式,
假使常量表明式为一个未定义的宏, 那么它的值被视为0.

could not determine file timestamp”
无法决定文件的时间戳”

#if MACRO_NON_DEFINED== #if 0

could not determine date and time”
手足无措决定日期与时间”

在认清某些宏是还是不是被定义时, 应当制止选取#if,
因为该宏的值或然便是被定义为0. 而应该选用下边介绍的#ifdef或#ifndef.

__COUNTER__ expanded inside directive with -fdirectives-only”
带 -fdirectives-only 时 __COUNTER__ 在训示中扩展”

注意: #if, #elif, #else之后的宏只可以是指标宏. 若是name为名的宏未定义,
或许该宏是函数宏. 那么在gcc中动用”-Wundef”选项会呈现宏未定义的警示新闻.

invalid string literal, ignoring final ‘\\’”
失效的字面字符串,忽略最后的‘\\’”

4, #ifdef, #ifndef, defined.

pasting \”%s\” and \”%s\” does not give a valid preprocessing
token”
交界“%s”和“%s”不能够交付2个一蹴而就的预处理标识符”

#ifdef, #ifndef, defined用来测试某些宏是不是被定义

ISO C99 requires rest arguments to be used”
ISO C99 须求运用剩余的参数”

#ifdef name  或 #ifndef name

macro \”%s\” requires %u arguments, but only %u given”
宏“%s”需求 %u 个参数,但只交付了 %u 个”

它们平日用来幸免头文件的再度引用:

macro \”%s\” passed %u arguments, but takes just %u”
宏“%s”传递了 %u 个参数,但只供给 %u 个”

#ifndef __FILE_H__

unterminated argument list invoking macro \”%s\””
调用宏“%s”时参数列表未甘休”

#define __FILE_H__

function-like macro \”%s\” must be used with arguments in traditional
C”
看似函数的宏“%s”在观念 C 中必须与参数一起使用”

#include “file.h”

invoking macro %s argument %d: empty macro arguments are undefined in
ISO C90 and ISO C++98″
调用宏 %s 的参数 %d:空的宏参数未被 ISO C90 和 ISO C++98 定义”

#endif

duplicate macro parameter \”%s\””
再次的宏参数“%s””

defined(name): 若宏被定义,则赶回1, 不然赶回0.

\”%s\” may not appear in macro parameter list”
“%s”不能冒出在宏参数列表中”

它与#if, #elif, #else结合使用来判断宏是不是被定义,
乍一看好像它显得多余, 因为早已有了#ifdef和#ifndef.
defined用于在一条判断语句中扬言五个判别条件:

macro parameters must be comma-separated”
宏参数必须由逗号隔离”

#if defined(VAX) && defined(UNIX) && !defined(DEBUG)

parameter name missing”
缺少形参名”

和#if, #elif, #else不同, #indef, #ifndef,
defined测试的宏能够是对象宏, 也足以是函数宏.
在gcc中利用”-Wundef”选项不会议及展览示宏未定义的警示信息.

anonymous variadic macros were introduced in C99″
匿名可变参数宏在 C99 中被引入”

5, #include , #include_next

ISO C does not permit named variadic macros”
ISO C 不相同意有名的可变参数宏”

#include用于文件包涵. 在#include
命令所在的行无法含有除注释和空白符之外的别的任何内容.

missing ‘)’ in macro parameter list”
在宏参数表中缺失‘)’”

#include “headfile”

‘##’ cannot appear at either end of a macro expansion”
‘##’不能够冒出在宏展开的多头”

#include

ISO C99 requires whitespace after the macro name”
ISO C99 要求宏名后必须有空落落”

#include 预处理标记

missing whitespace after the macro name”
宏名后缺乏空白”

前方三种格局大家都很熟练, “#include 预处理标记”中,
预处理标记会被预处理器实行轮换, 替换的结果必须符合前三种格局中的某一种.

‘#’ is not followed by a macro parameter”
‘#’后不曾宏参数”

实际, 真正被添加的头文件并不一定即是#include中所钦命的文件.
#include”headfile”包蕴的头文件当然是同3个文书, 但#include
包包含的”系统头文件”恐怕是此外的文件. 但那不值得被注意.
感兴趣的话能够查看宏扩展后到底引入了什么系统头文件.

\”%s\” redefined”
“%s”重定义”

关于#include “headfile”和#include
的区别以及如何在gcc中带有头文件的详细音讯, 参考本blog的GCC笔记.

this is the location of the previous definition”
那是先前定义的职位”

相对于#include, 我们对#include_next不太熟识.
#include_next仅用于特殊的场所.
它被用来头文件中(#include既可用于头文件中,
又可用于.c文件中)来含有其余的头文件. 而且蕴藏头文件的路子比较奇特:
从当下头文件所在目录之后的目录来搜索头文件.

macro argument \”%s\” would be stringified in traditional C”
宏参数“%s”将在观念 C 中被字符串化”

诸如: 头文件的查找路径1遍为A,B,C,D,E.
#include_next所在的近日头文件位于B目录,
那么#include_next使得预处理器从C,D,E目录来探寻#include_next所钦定的头文件.

invalid hash type %d in cpp_macro_definition”
cpp_macro_definition 中有不行的散列类型 %d”

可参考cpp手册越是询问#include_next

while writing precompiled header”
在写入预编写翻译头时”

6, 预订义宏

%s: not used because `%.*s’ is poisoned”
%s:未使用因为‘%.*s’已被投毒”

标准C中定义了部分对象宏, 这么些宏的名号以”__”早先和终极,
并且都是大写字符. 那一个预约义宏可以被#undef, 也得以被重定义.

%s: not used because `%.*s’ not defined”
%s:未使用因为‘%.*s’未定义”

下边列出一部分标准C中普遍的预约义对象宏(在那之中也包蕴gcc自个儿定义的一些预约义宏:

%s: not used because `%.*s’ defined as `%s’ not `%.*s’”
%s:未使用因为‘%.*s’被定义为‘%s’而非‘%*.s’”

__LINE__当前说话所在的行号, 以10进制整数标注.

%s: not used because `%s’ is defined”
%s:未利用因为‘%s’已定义”

__FILE__此时此刻源文件的公文名, 以字符串常量标注.

%s: not used because `__COUNTER__’ is invalid”
%s:未使用因为‘__COUNTER__’无效”

__DATE__先后被编写翻译的日期, 以”Mmm dd yyyy”格式的字符串标注.

while reading precompiled header”
在读取预编写翻译头时”

__TIME__先后被编写翻译的时间, 以”hh:mm:ss”格式的字符串标注,
该时间由asctime重返.

detected recursion whilst expanding macro \”%s\””
展开宏“%s”时检查和测试到递归”

__STDC__比方当前编写翻译器符合ISO标准, 那么该宏的值为1

syntax error in macro parameter list”
宏参数列表语法错误”

__STDC_VERSION__若果当前编写翻译器符合C89, 那么它被定义为一九九一09L,
假诺符合C99, 那么被定义为一九九八01L.

#~ warning: ”
#~ 警告:”

自己用gcc, 就算不点名-std=c99,
别的情状都交给__STDC_VERSION__未定义的错误音信, 咋回事呢?

#~ internal error: ”
#~ 内部错误:”

__STDC_HOSTED__假如当前系统是”本地系统(hosted)”, 那么它被定义为1.
地点系统表示近期系统具备完整的正统C库.

#~ error: ”
#~ 错误:”

gcc定义的预订义宏:

#~ In file included from %s:%u”
#~ 在蕴藏自 %s:%u 的文本中”

__OPTMIZE__借使编写翻译进度中央银行使了优化, 那么该宏被定义为1.

#~ ”
#~ “,\n”
#~ ” from %s:%u”
#~ ”
#~ “,\n”
#~ ” 从 %s:%u”

__OPTMIZE_SIZE__同上,
但仅在优化是指向代码大小而非速度时才被定义为1.

#~ no newline at end of file”
#~ 文件未以空白行停止”

__VERSION__彰显所用gcc的本子号.

可参考”GCC the complete reference”.

要想见见gcc所定义的拥有预订义宏, 能够运行: $ cpp -dM /dev/null

7, #line

#line用来修改__LINE__和__FILE__.

e.g.

printf(“line: %d, file: %s\n”, __LINE__, __FILE__);

#line 100 “haha”

printf(“line: %d, file: %s\n”, __LINE__, __FILE__);

printf(“line: %d, file: %s\n”, __LINE__, __FILE__);

显示:

line: 34, file: 1.c

line: 100, file: haha

line: 101, file: haha

8, #pragma, _Pragma

#pragma用编写翻译器用来添加新的预处理效果还是展现一些编译音讯.
#pragma的格式是各编写翻译器特定的, gcc的如下:

#pragma GCC name token(s)

#pragma之后有多个部分: GCC和一定的pragma name. 上边分别介绍gcc中常用的.

(1) #pragma GCC dependency

dependency测试当前文件(既该语句所在的程序代码)与钦定文件(既#pragma语句最终列出的公文)的小运戳.
假使内定文件比方今文件新, 则交给警告音信.

e.g.

在demo.c中付出那样一句:

#pragma GCC dependency “temp-file”

然后在demo.c所在的目录新建3个更新的公文: $touch temp-file, 编写翻译: $gcc
demo.c会付给那样的警告消息:warning: current file is older than temp-file

比方当前文件比钦定的公文新, 则不给出任何警告新闻.

还是可以在在#pragma中给添加自定义的警告新闻.

e.g.

#pragma GCC dependency “temp-file” “demo.c needs to be updated!”

1.c:27:38: warning: extra tokens at end of #pragma directive

1.c:27:38: warning: current file is older than temp-file

专注: 后边新增的警示消息要用””引用起来, 否则gcc将送交通警务人员告音信.

(2) #pragma GCC poison token(s)

若源代码中出现了#pragma中提交的token(s), 则编译时展现警告消息.
它一般用来在调用你不想行使的函数时候给出出错新闻.

e.g.

#pragma GCC poison scanf

scanf(“%d”, &a);

warning: extra tokens at end of #pragma directive

error: attempt to use poisoned “scanf”

在意, 假若调用了poison中付出的标记, 那么编译器会付给的是失误音讯.
关于率先条警告, 笔者还不精通怎么幸免, 用””将token(s)引用起来也不行.

(3) #pragma GCC system_header

从#pragma GCC
system_header直到文件停止之间的代码会被编写翻译器视为系统头文件之中的代码.
系统头文件中的代码往往不可能完全依据C标准,
所以头文件之中的警戒音信往往不展现. (除非用 #warning显式指明).

(这条#pragma语句还没觉察用哪些大的用途

)

由于#pragma不可能用来宏扩张, 所以gcc还提供了_Pragma:

e.g.

#define PRAGMA_DEP #pragma GCC dependency “temp-file”

由于预处理之进行一遍宏扩大, 接纳地点的方法会在编写翻译时引发错误,
要将#pragma语句定义成四个宏扩张, 应该利用下边包车型客车_Pragma语句:

#define PRAGMA_DEP _Pragma(“GCC dependency \”temp-file\””)

注意, ()中包涵的””引用此前引该加上\转义字符.

9, #, ##

#和##用来对字符串的预处理操作, 所以他们也时常用来printf,
puts之类的字符串展现函数中.

#用以在宏扩展之后将tokens转换为以tokens为内容的字符串常量.

e.g.

#define TEST(a,b) printf( #a “<” #b “=%d\n”, (a)<(b));

注意: #只针对紧随其后的token有效!

##用以将它左右的四个token组合在同步转换来以那多少个token为内容的字符串常量.
注意##左右供给求有token.

e.g.

#define TYPE(type, n) type n

从此现在调用:

TYPE(int, a) = 1;

TYPE(long, b) = 1999;

将被调换为:

int a = 1;

long b = 1999;

(10) #warning, #error

#warning, #error分别用于在编写翻译时展示警告和错误音讯, 格式如下:

#warning tokens

#error tokens

e.g.

#warning “some warning”

注意, #error和#warning后的token要用””引用起来!

(在gcc中, 借使给出了warning, 编写翻译继续展开, 但若给出了error, 则编译结束.
若在指令行中钦命了 -Werror, 纵然唯有警告音讯, 也不编写翻译.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有