首页 > 解决方案 > 用字符串文字初始化 uint8_t 数组是否合法?

问题描述

uint8_t从字符串文字初始化数组可以吗?它是按预期工作还是由于有符号-无符号转换而破坏了一些字节?(我希望它只是将文字的部分原封不动地塞进去。) GCC 不会抱怨,-Wall而且它似乎可以工作。

const uint8_t hello[] = "Hello World"

我正在使用一个将字符串作为uint8_t *. 现在我正在使用演员表,否则我会收到警告:

const char* hello = "Hello World\n"
HAL_UART_Transmit(uart, (uint8_t *)hello, 12, 50);
// HAL_UART_Transmit(uart, hello, 12, 50);
// would give a warning such as:
// pointer targets in passing argument 2 of 'HAL_UART_Transmit' differ in signedness [-Wpointer-sign]

在这个平台上,char是 8 位和有符号的。在那种情况下可以使用uint8_t代替char吗?请不要专注于 constness 问题,API 应该采用const uint8_t *但不采用。这个 API 调用只是让我想到这个问题的例子。


令人讨厌的是,这个问题现在已经结束,我想自己回答。抱歉在此处添加此信息,我无权重新打开。

以下所有内容都适用于gcc -Wall -pedantic,但第四个警告将有符号转换为无符号。内存中的位模式将是相同的,并且如果您将这样的对象强制转换为(uint8_t *)它将具有相同的行为。根据标记的 duplicate,这是因为您可以将字符串文字分配给任何 char 数组。

const char string1[] = "Hello";
const uint8_t string2[] = "Hello";
uint8_t string3[] = "Hello";
uint8_t* string4 = "Hello";
char* string5 = "Hello";

当然,只有前两个是值得推荐的,因为您不应该尝试修改字符串文字。在上面的具体情况下,您可以创建一个包装函数/宏,或者只是将强制转换保留在内部作为对 API 的让步,然后一天结束。

标签: cstdint

解决方案


C 2018 6.7.9 14 告诉我们“字符类型的数组可以由字符串文字或 UTF-8 字符串文字初始化……”</p>

C 2018 6.2.5 15 告诉我们“这三种类型char, signed char, 和unsigned char统称为字符类型。”</p>

C 2018 6.2.5 4 和 6.2.5 6 表示可能有扩展整数类型

没有声明任何扩展整数类型都是字符类型。

C 2018 7.20 4 告诉我们“对于此处描述的实现提供的每种类型,<stdint.h>应声明 typedef 名称......”和 7.20.1 5 告诉我们“当 typedef 名称仅在不存在或存在首字母u时有所不同时,它们应表示相应的有符号和无符号类型,如 6.2.5 中所述……”</p>

因此,C 实现可以提供一个无符号 8 位类型,它是扩展整数类型,而不是unsigned char, 并且可以定义uint8_t为这种类型,然后 6.7.9 14 并没有告诉我们可以初始化这种类型的数组通过字符串文字。

如果一个实现允许您uint8_t使用字符串字面量初始化一个数组,那么它要么定义uint8_t为 unsignedchar或 to unsigned char,要么定义uint8_t为扩展整数类型,但允许您将数组初始化为 C 语言的扩展标准。由 C 实现来定义该扩展的行为,但我希望它能够像初始化字符类型数组一样工作。

(可以想象,定义uint8_t为扩展整数类型并不允许将其视为字符类型可能有助于区分允许为任何对象起别名的字符类型与不允许此类别名的纯整数类型。这可能允许编译器执行额外的优化,因为它知道别名不会发生,或者可能诊断某些错误。)

字符串文字的元素具有类型char(按 C 2018 5.2.1 6)。C 2018 6.7.9 14 告诉我们“字符串文字的连续字节......初始化数组的元素。” 每个字节都应该以通常的方式初始化一个数组元素,包括根据 C 2018 6.7.9 11 转换为目标类型。对于您显示的字符串"Hello World",字符值都是非负的,因此在转换它们时没有问题char值为uint8_t. 如果字符串中有负数字符,则应以uint8_t通常的方式将它们转换为。

(如果您的八进制或十六进制转义序列的值未在 a 中表示char,则初始化中可能会有一些语言律师的怪异。)


推荐阅读