“#define setId(ptr, value) ((ptr)->id = (value), 0) 是什么意思
what is the meaning of "#define setId(ptr, value) ((ptr)->id = (value), 0)
当我阅读某人的代码时,我遇到了陌生的代码。
代码如下:
struct Employee {
int id;
};
#define getId(ptr) ((ptr)->id)
#define setId(ptr, value) ((ptr)->id = (value), 0)
我无法理解 ((ptr)->id = (value), 0)
。
这个宏和 ((ptr)->id = (value)
一样吗?
您发布的代码似乎有误:
#define setId(ptr, name) ((ptr)->id = (id), 0)
setId
宏可能应该使用 name
参数而不是某些本地 id
标识符。如果 name
是一个整数,它可能是这样的:
#define setId(ptr, name) ((ptr)->id = (name), 0)
否则,它可能是这样的:
#define setId(ptr, name) ((ptr)->id = nameToId(name), 0)
关于, 0)
部分,它是逗号运算符的一个实例:宏扩展为一个表达式,先计算赋值,然后计算0
。如果使用 setId(ptr, name)
的结果,其值将始终为 0
。像这样的结构可读性不强,可能会在某些编译器上产生警告。
I couldn't understand of ((ptr)->id = (id), 0)
. Is this macro the
same like ((ptr)->id = (id)
?
,
是预处理器宏中的 comma operator used in a complex return context。
所以当你叫你macro时,它会设置员工的id然后return 0
(这只是程序员的设计决定,可能只是为了return 0
意思是 "no error").
但是正如其他人在评论中指出的那样,宏的定义可能有错误,它应该看起来像:
#define setId(ptr) ((ptr)->id = (id), 0)
I couldn't understand of "((ptr)->id = (id), 0)". Is this macro the same like "((ptr)->id = (id)" ?
假设宏定义为:
#define setId(ptr, name) ((ptr)->id = (name), 0)
如果你有一个表达式
a = setId(ptr, name);
扩展为
a = ((ptr)->id = (name), 0);
执行该表达式时,a
的值为0
,即逗号表达式((ptr)->id = (name), 0)
的值。计算表达式的副作用是 ptr
指向的对象的 id
成员设置为 name
.
这些宏取代了 "setter" 和 "getter" 函数。假设 "setter" 应该 return 0 表示成功,-1 表示失败,函数看起来像这样
int getId( struct Employee *ptr )
{
return( ptr->id );
}
int setId( struct Employee *ptr, int value )
{
ptr->id = id;
return 0; // this setter always succeeds
}
用宏替换 getter 很简单。替换 setter 有点棘手,因为您需要 "return" 正确的值。这就是逗号运算符的用武之地。
逗号运算符计算第一个表达式并丢弃结果。然后计算第二个表达式,第二个表达式的结果用作逗号运算符的结果。因此 setter 宏的计算结果始终为 0。
当我阅读某人的代码时,我遇到了陌生的代码。 代码如下:
struct Employee {
int id;
};
#define getId(ptr) ((ptr)->id)
#define setId(ptr, value) ((ptr)->id = (value), 0)
我无法理解 ((ptr)->id = (value), 0)
。
这个宏和 ((ptr)->id = (value)
一样吗?
您发布的代码似乎有误:
#define setId(ptr, name) ((ptr)->id = (id), 0)
setId
宏可能应该使用 name
参数而不是某些本地 id
标识符。如果 name
是一个整数,它可能是这样的:
#define setId(ptr, name) ((ptr)->id = (name), 0)
否则,它可能是这样的:
#define setId(ptr, name) ((ptr)->id = nameToId(name), 0)
关于, 0)
部分,它是逗号运算符的一个实例:宏扩展为一个表达式,先计算赋值,然后计算0
。如果使用 setId(ptr, name)
的结果,其值将始终为 0
。像这样的结构可读性不强,可能会在某些编译器上产生警告。
I couldn't understand of
((ptr)->id = (id), 0)
. Is this macro the same like((ptr)->id = (id)
?
,
是预处理器宏中的 comma operator used in a complex return context。
所以当你叫你macro时,它会设置员工的id然后return 0
(这只是程序员的设计决定,可能只是为了return 0
意思是 "no error").
但是正如其他人在评论中指出的那样,宏的定义可能有错误,它应该看起来像:
#define setId(ptr) ((ptr)->id = (id), 0)
I couldn't understand of "((ptr)->id = (id), 0)". Is this macro the same like "((ptr)->id = (id)" ?
假设宏定义为:
#define setId(ptr, name) ((ptr)->id = (name), 0)
如果你有一个表达式
a = setId(ptr, name);
扩展为
a = ((ptr)->id = (name), 0);
执行该表达式时,a
的值为0
,即逗号表达式((ptr)->id = (name), 0)
的值。计算表达式的副作用是 ptr
指向的对象的 id
成员设置为 name
.
这些宏取代了 "setter" 和 "getter" 函数。假设 "setter" 应该 return 0 表示成功,-1 表示失败,函数看起来像这样
int getId( struct Employee *ptr )
{
return( ptr->id );
}
int setId( struct Employee *ptr, int value )
{
ptr->id = id;
return 0; // this setter always succeeds
}
用宏替换 getter 很简单。替换 setter 有点棘手,因为您需要 "return" 正确的值。这就是逗号运算符的用武之地。
逗号运算符计算第一个表达式并丢弃结果。然后计算第二个表达式,第二个表达式的结果用作逗号运算符的结果。因此 setter 宏的计算结果始终为 0。