C诡异离奇,缺陷重重,却获得了巨大的成功 -- Dennis Ritchie
#define a(y) a_expanded(y)
a(x);
被扩展为
a_expanded(x); // 待有分号
而
#define a (y) a_expanded (y)
a(x)
则扩展为
(y) a_expanded (y) (x)
// 宏定义
#define STRING char *
#define IF if(
#define THEN ){
#define ELSE }else{
#define FI ;}
#define WHILE while(
#define DO ){
#define OD ;}
#define INT int
#define BEGIN {
#define END
// 宏使用
INT compare(s1, s2)
STRING s1;
STRING s2;
BEGIN
WHILE *a1++ == *a2
DO IF *s2++ == 0
THEN return(0);
FI
OD
return(*--s1 - *s2);
END
// 复合赋值符号
b=-3 /* 从b中减去3 */
b= -3 /* 把-3赋给b */
valve=!open; /* valve 被设置为open的逻辑取反 */
value!=open; /* valve 与 open进行不相等比较 */
foo(const char **p){ }
main(int argc, char **argv)
{
foo(arvg);
}
编译这段代码,编译器会发出一条告警信息:
line 5: warning: argument is incompatible with prototype
ANSI C 标准:
每个实参都应该具有自己的类型,这样它的值就可以赋值给它所对应的形参类型对象。(该对象的类型不能含有限定符)。
说明:参数传递过程类似于赋值。所以除非一个类型为char ** 的值可以赋值给一个const char **类型的对象。否则肯定会产生一条诊断信息。
要使赋值形式合法,需要满足如下条件:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针指向类型的全部限定符。