Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 根据类型转换的方式将类型转换包含在#定义的常量中是否合理';你打算用什么?_C - Fatal编程技术网

C 根据类型转换的方式将类型转换包含在#定义的常量中是否合理';你打算用什么?

C 根据类型转换的方式将类型转换包含在#定义的常量中是否合理';你打算用什么?,c,C,假设我有一堆未经想象的常量,这些常量在陀螺仪模块的头文件gyro.h中给出了符号名称: #define GYRO_SPI_TIMEOUT 1000 在本例中,我的MCU的硬件抽象库使用uint32\u t表示毫秒数。在宏中添加类型信息,而不是分配空间并将其定义为const,是否明智 #define GYRO_SPI_TIMEOUT ((uint32_t) 1000) 这种方法的优点和缺点是什么?是的,经常这样做。事实上,臭名昭著的NULL指针通常是这样定义的: #定义空((void*)0)

假设我有一堆未经想象的常量,这些常量在陀螺仪模块的头文件
gyro.h
中给出了符号名称:

#define GYRO_SPI_TIMEOUT 1000
在本例中,我的MCU的硬件抽象库使用
uint32\u t
表示毫秒数。在宏中添加类型信息,而不是分配空间并将其定义为
const
,是否明智

#define GYRO_SPI_TIMEOUT ((uint32_t) 1000)

这种方法的优点和缺点是什么?

是的,经常这样做。事实上,臭名昭著的
NULL
指针通常是这样定义的:

#定义空((void*)0)

优点:无论全局常量支持者怎么说,您的宏现在都是类型安全的

缺点:如果您想以不安全的方式使用它,可以这样说:

short a=陀螺SPI超时


你需要一个演员。但是,如果你不打算使用这种用法,这可能是件好事。

我会认为这是一件好事,尤其是确保正确的图形性(为此目的,<代码> 1000 U < /代码>就足够了)。算术类型在C中不是强类型的,因此,如果宏扩展具有正确的符号并被提升(即不小于
int
),则大多数代码不会更改语义


<> P>有编译器的静态分析器和选项,但是,它会做更多的类型检查,不允许某些隐式转换,如果你的常量用你的头来表示代码,那么你的常量就好像是变量,那就太好了。(您可能需要向下滚动到显示“整数常量表达式宏”的位置)

与强制转换相比,这些宏的主要优点是使用它们定义的常量可以在更多上下文中使用。例如,
((uint32_t)1234)
不能出现在
#if
表达式中,但
uint32_C(1234)
可以

请注意,大多数C编译器不会抱怨常数表达式的赋值涉及到缩小转换,除非转换实际改变了值

short a = 1234UL;
short b = ((unsigned long)1234);
short c = 65537UL;
short d = ((unsigned long)65537);

gcc 4.9和clang 3.5仅为
c
d
发布转换诊断,即使我将警告设置得尽可能高。

当您可以使用
1000U
时,很难看到有什么好处有任何实际原因需要进行额外转换吗?在大多数情况下,您不需要它:例如,对于赋值给我在uint32_t中使用nt,或将值传递给带有
uint32_t
参数的函数。对于极少数需要强制转换的情况,可以显式添加它。@HansPassant:它不同。下面是一个示例:
short s=((uint32_t)1000)
-不编译;
short s=1000U
编译。看来您使用的
UINTN\u C
宏是正确的。尽管您的上一个语句似乎与文档不一致。宏将扩展为整数常量
1234UL
(或者任何Ls的组合将使其至少宽32位)。当您将其分配给较短的值时,应该会生成一个警告,对吗?@josaphatv大多数编译器都会默默地接受
short a=
,而不管整型文字的后缀是什么,除非该分配实际更改了数值。因此,
short a=1234UL;
毫无怨言地通过,但
short a=65537UL;
警告。@josaphatv……经过实验,我也无法说服gcc警告
短a=((无符号长)1234)
,即使设置了荒谬的攻击性警告也不行。建议使用
[U]INT\U C
在这里并没有阐明一个要点:
UINT32\U C(1234)
不创建类型
uint32\u t
,而是
uint32\u t