【发布时间】:2018-05-18 12:33:29
【问题描述】:
我想在 C99 中创建一个 struct,它封装了一个以 null 结尾的字符串缓冲区以及实际的字符串长度:
typedef unsigned int uint_t;
typedef unsigned char uchar_t;
typedef struct {
uchar_t * buffer;
uint_t length; // excluding null-terminating character
} string_t;
但是,我在struct 成员的const-ness 方面遇到了一些困难。具体来说,当我想使用一个接受这种const struct string_t 的函数,并用一个带有 const 成员的初始化程序来提供它时,编译器会对我大喊大叫。
void show_string_internal(const string_t str) {
printf("%s", str.buffer);
}
void show_string(const uchar_t * buffer, uint_t length) {
const string_t str = // <== tricky assignment here
(const string_t){ buffer, length };
show_string_internal(str);
}
int main() {
uchar_t message[] = "Hello, world.";
show_string(message, sizeof(message) - 1);
return 0;
}
这会在 GCC 中突出显示的行上产生警告...:
警告:初始化会丢弃指针目标类型中的 'const' 限定符
...在 Visual Studio 2015 中:
警告 C4090:“正在初始化”:不同的“const”限定符
显然,我在这里做错了什么。我发现解决这个问题的唯一方法是声明:
typedef struct {
const uchar_t * buffer;
const uint_t length;
} const_string_t;
但现在我有两种类型而不是一种,所以我需要创建方便的方法来在两者之间进行转换,而且我正在创建声明性糖而不是使用语言功能,因此代码的可读性较差。
所以我的问题是,正如标题所述:有没有办法使用成员的const 变量来初始化const struct?是否有其他方法可以达到我希望达到的结果?如果没有,为什么不(请附上官方文档的参考资料)?
任何帮助将不胜感激。
【问题讨论】:
-
你能在出现女巫错误时标记行吗
-
你为什么不制作字符串的硬拷贝?没有它,
string_t似乎毫无用处。 -
这根本没有多大意义。你甚至不需要在你的变量定义中有
const。 -
即你在太多地方使用了
const,而且没有任何意义。 -
另外,
uchar_t *与char *是什么关系 - 它们不是相等的类型。