我正在读这里的代码: https://github.com/chenshuo/muduo/blob/master/muduo/base/Date.cc
但我对这两行感到困惑:
char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1];
和
(void) require_32_bit_integer_at_least; // no warning please
他们的目的是什么?
char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1];
int getJulianDayNumber(int year, int month, int day)
{
(void) require_32_bit_integer_at_least; // no warning please
int a = (14 - month) / 12;
int y = year + 4800 - a;
int m = month + 12 * a - 3;
return day + (153*m + 2) / 5 + y*365 + y/4 - y/100 + y/400 - 32045;
}
答案 0 :(得分:7)
代码要求SELECT
user_id,
count(*) as total,
sum(case when user_name LIKE '%jeff%' then 1 else 0 end) as jeff_count
FROM logins
WHERE login_date BETWEEN "2015-09-01" AND "2016-09-01"
GROUP BY user_id;
至少为32位宽。
如果不是这种情况并且SELECT *
FROM mytable
ORDER BY Status DESC,
CASE
WHEN Status = 1 THEN DATEDIFF(Date, '1900-01-01')
ELSE DATEDIFF('1900-01-01', Date)
END
小于32位,则会出现如下错误:
int
该行
sizeof(int)
似乎是为了避免“未使用的变量”警告。但是,由于数组是全局和非静态的,因此无论如何编译器都不会生成警告。 知道全局非静态变量确实未使用将需要检查整个项目中的所有翻译单元(源文件)。
正如@MartinBonner所提出的,为了使它更清晰,更容易使用,我们可以定义一个“静态断言”宏:
error: size of array 'require_32_bit_integer_at_least' is negative
并按如下方式使用:
(void) require_32_bit_integer_at_least; // no warning please
答案 1 :(得分:1)
char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1];
在运行方法中的任何实际代码之前声明一个数组。如果int的大小小于32位(例如,int为24或16位的编译器),那么它将尝试创建大小为-1的数组,这是不允许的并且将导致错误,意味着代码不会运行。
第(void) require_32_bit_integer_at_least; // no warning please
行阻止编译器抱怨未使用的数组。
答案 2 :(得分:1)
在C ++ 11及更高版本中,只需使用标准 static_assert
。
您正在研究一种特定的C ++ 03技术来实现静态(即编译时)断言。
另一种技术使用嵌套在类模板中的typedef
类型,它没有false
模板参数的嵌套类型。这样做的一个优点是typedef
几乎可以在任何地方出现,并且可以用相同的定义重复(除非编译器不符合,就像当时一样)。该技术可以进一步阐述,以提供一个体面的信息错误信息,安德烈亚历山大夫斯库在他现在的经典“现代C ++设计”一书中探讨过。
那怎么样?
char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1];
...作为静态断言工作?
如果数组大小为-1
,则代码格式不正确。
数组大小0
也会形成错误,但有些编译器会错误地接受它;因此条件运算符(或在某些情况下是算术表达式)而不是简单的布尔值。
在本地范围内使用断言,以下
(void) require_32_bit_integer_at_least; // no warning please
...会完全按照评论解释的那样:它会抑制关于未使用变量的可能警告。
但是,在原始代码中,assert位于命名空间范围内,并且转换为函数内的void
。这对标准C ++来说毫无意义。一个可能的原因可能是特定的编译器优化了断言变量,并且错误地接受了断言不存在的代码,并且变量的本地使用阻止了该行为,然后注释完全误导。