xml地图|网站地图|网站标签 [设为首页] [加入收藏]
来自 每日资讯 2019-10-14 12:42 的文章
当前位置: 新濠国际登录平台 > 每日资讯 > 正文

新濠国际登录平台本地是不能用啊,编译预处理

转载:

 

【引用 《智能家电控制技术》帮助文档  这里有很是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语言规定,函数调用的各参数之间必须以逗号分隔,并以右括号结束,若源文件中含有一个其后不是逗号也不是右括号的参数,则会出现本错误。
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-16位的常量表达式。
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后面的第一个非空格符号必须是一个标识符,若编译程序发现一些其他字符,则出现本错。
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必须有一个唯一的常量表达式。
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下的文件名不能超过64个字符。
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
宏扩展太长。一个宏扩展不能多于4096个字符。当宏递归扩展自身时,常出现本错误。宏不能对自身进行扩展。
72.         may compile only one file when an output file name is given
给出的一个输出文件名时,可能只编译一个文件。在命令编译时,若使用-o选择,则至于需一个输出文件名。此时,只编译第一个文件,其他文件被忽略。
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
对不可移植的指针赋值。原程序将一个指针赋给一个非指针,或相反。但作为特例允许把常量零值赋给一个指针,如果是这种情况,可以强行抑制本错误信息。
86.         non-portable pointer comparison
不可移植的指针比较。源程序中将一个指针与一个非指针(常量零除外)进行比较。但如果比较恰当,则应强行抑制本错误信息。
87.         non-portable return type conversion
不可移植的返回类型转换。在返回语句中的表达式类型与函数说明中的类型不同。但如果函数的返回表达式是一指针,则可以进行转换,此时,返回指针的函数可能送回一个常量零,而零被转换成一个适当的指针值。
88.         not an allowed type
不允许的类型,在源文件中说明了几种禁止了的类型,如函数返回一个函数或数组。
89.         out of memory
内存不够。
90.         pointer required o left side of
操作符左边须是一个指针
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语句最多允许有257个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#
"#"参数类型不匹配。通过一个指针访问已由原型说明的参数时,给定参数#N(从左到右N逐个加1)不能转换为已说明的参数类型。
112.         type mismatch in parameter # in call to ‘xxxxxxx’
调用“xxxxxx”参数#类型不匹配。源文件中通过一个原型中说明了指定的参数,而给定的参数(从左到右N逐个加1)不能转换为已说明的参数类型。
113.         type mismatch in parameter ‘xxxxxx’
参数"yyyyyy"类型不匹配。源文件中通过一个原型说明了可以有函数指针调用的函数,而所制定的参数不能转化为另一个已说明的参数类型。
114.         type mismatch in parameter ‘xxxxxxx’ in call to ‘yyyyyyyy’
调用“xxxxxx”时,参数"xxxxxx"类型不匹配。源文件中通过一个原型说明指定的参数。而所制定的参数不能转化为另一个已说明的参数类型。
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 setn”
字符 0x%lx 不在基本源字符集中n”

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

编译预处理命令的语法与C语言的语法是完全独立的. 比如: 你可以将一个宏扩展为与C语法格格不入的内容, 但该内容与后面的语句结合在一个若能生成合法的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语句

%.*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)连接为一个单独的标记

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的原因是为了让WARN_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 ("%sn",str(foo));
    printf ("%sn",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("%sn",S(_G(A,B)));
    printf("%sn",_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 是一个已过时的 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命令定义一个宏:

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 中文件名为空”

   至于单独一个#,则表示 对这个变量替换后,再加双引号引起来。比如

#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中可使用的预定义宏涵盖了如下几方面的信息:
      1、宿主的信息:GNU的版本,编译器的版本,类型的相关信息,字节序信息等。
      2、编译动作的信息:编译的日期、时间;编译时是否进行了时间或空间上的优化;定义的inline是否被编译器执行等。
      3、文件的信息:文件名称、函数名称、行数信息、文件最后修改时间等等。
      4、计数信息:__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 __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.

本文由新濠国际登录平台发布于每日资讯,转载请注明出处:新濠国际登录平台本地是不能用啊,编译预处理

关键词: