符号常量的“类型”是什么?

7
  1. When is it appropriate to include a type conversion in a symbolic constant/macro, like this:

    #define MIN_BUF_SIZE ((size_t) 256)
    

    Is it a good way to make it behave more like a real variable, with type checking?

  2. When is it appropriate to use the L or U (or LL) suffixes:

    #define NBULLETS 8U
    #define SEEK_TO 150L
    

只需记住宏只是复制+粘贴。因此,它将采取上下文所确定的任何类型。 - Mysticial
如果在宏的位置需要强制转换,那么每次放置宏时都需要添加强制转换。按照您提出的方式执行可能会节省您的打字时间(也许还有一些调试时间 ;-))。 - alk
1
不要在意“表现得更像真正的变量”。当然,字面值256本身也会有一个类型。 - potrzebie
4个回答

4

在自动转换不适用的情况下,特别是对于具有可变参数列表的函数,键入常量可能非常重要。

printf("my size is %zu\n", MIN_BUF_SIZE);

当int和size_t的宽度不同时,如果不进行转换,代码很容易崩溃。

但是您的宏还有改进的空间。我会这样做:

#define MIN_BUF_SIZE ((size_t)+256U)

(注意那里的小加号 +

即使这样提供宏,它仍然可以在预处理器表达式中使用(使用 #if)。这是因为在预处理器中,(size_t) 计算结果为 0,因此结果也是无符号的 256


我喜欢你的第一个示例。gccclang(以及可能还有其他编译器)现在会发出关于不匹配格式/参数对的警告。 - Carl Norum
1
警告通常被忽略,在平台不同的情况下(例如,具有32位int的64位平台),它们无法保护您免受未定义的行为。我认为定义常量以使行为始终正确是一个好方法。 - Jules

4

每当默认类型不合适时,您需要进行更改。就是这样。


0

#define 只是一个标记粘贴预处理器。

无论你在 #define 中写什么,它都会在编译之前被替换为替换文本。

因此,两种方式都是正确的。

#define A a

int main
{
 int A; // A will be replaced by a
}

在编程中,有许多关于 #define 的变化,例如可变参数宏多行宏

但是,#define 的主要目的只有上面解释的那一个。


0

在 Kernighan 和 Richie C(在 ANSI/Standard C 及其函数原型出现之前)中,显式指定常量的类型更为相关。

函数原型如 double fabs(double value); 现在允许编译器在需要时生成适当的类型转换。

在某些情况下,您仍然希望明确指示常量的大小。我现在想到的例子是位掩码:

  • #define VALUE_1 ((short) -1) 可能有 16 位长,而 #define VALUE_2 ((char) -1) 可能只有 8 位。因此,对于一个 long xx & VALUE_1x & VALUE_2 将会得到非常不同的结果。

    • 这也适用于 L 或 LL 后缀:常量将使用不同数量的位。

给定一个 long xVALUE_1VALUE_2 将被提升并进行符号扩展,因此您应该得到相同的结果。 - Carl Norum
Carl,你是对的。太多了脑海中编出的例子了 :-/ - Luis
@Luis 假设你认为在讨论的实现中char是无符号的。 ;) - Daniel Fischer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接