我有一个结构数组,一些结构成员是常量我想做一个数组的深层副本.该副本也将具有与常量相同的结构成员.如何在不违反const指令的情况下将值初始化为新数组.
下面是我的代码的摘录.实际的程序很长,但我想我已经包含了所有相关的代码.在这个例子中,键被声明为一个全局变量,我想从中创建新的实例.我认为它有点像带预设值的模板.
当我尝试使用gcc在Debian中编译它时,我收到以下错误:
main.c:216:9: error: assignment of read-only location ‘*(new_keys + (unsigned int)((unsigned int)index * 540u))’make: *** [main.o] Error 1
makefile使用以下限定符:
CFLAGS=-c -g -std=gnu99 -D_XOPEN_SOURCE=700
有趣的是.即使为C语言方言GNU99设置了Xcode,我也可以在Xcode中编译相同的代码而不会出现错误或警告[-std = gnu99]
我可以简单地通过去除const关键字来使我的代码工作.但这些价值确实应该是常数.一旦这些数组初始化,它们将永远不会改变.我想了解如何正确地做到这一点,并且我想知道为什么这在Xcode而不是gcc中有效.
头文件
typedef struct { char * name; char * alias; int number; } pair_int_t; typedef struct { const char * const name; const kind_t kind; // kind is enum type const pair_int_t * const enum_array; bool received; const char * const alias; } key_descriptor_t; typedef key_descriptor_t keys_descriptor_t[_END_OF_KEYS+1];
main()之前的.c程序体
const pair_int_t command_list[] = { {.name = "numeric data response", .alias = "num", .number = RES_NUMERIC_DATA}, {.name = "read attribute", .alias = "readat", .number = CMD_READ_ATTR}, //.. } // declare a global variable *keys* with constants assigned to it key_descriptor_t keys[] = { [_COMMAND] = {.name = "command", .kind = ENUMERATED, .alias = "com", .enum_array = command_list}, [_RESPONSE] = {.name = "response", .kind = ENUMERATED, .alias = "res", .enum_array = command_list}, [_UNIT] = {.name = "unit number", .kind = NUMBER, .alias = "uni", .enum_array = NULL}, //.. } int initialize_new_keys(keys_descriptor_t new_keys) { int index; for (index = _FIRST_KEY; index <= _END_OF_KEYS; index++){ new_keys[index] = keys[index]; // line 216, keys is a global variable } return index; }
主程序
int main(int argc, const char * argv[]){ keys_descriptor_t 2nd_set_of_keys; initialize_new_keys(2nd_set_of_keys); }
Crowman.. 5
您只能const
在定义变量时初始化变量.创建一个包含const
成员的数组,将其发送到函数,然后尝试分配给这些成员,这意味着您const
首先并不是真正的意思.C中没有" const
除第一次分配外"的语法.
一个合理的替代方法是创建一个opaque类型,将定义封装在一个单独的转换单元中,然后纯粹通过函数接口访问所有成员.这样,即使事情可能不存在const
,它们仍然无法更改(除非通过故意的颠覆,这至少不比不首先调用事物const
好),因为没有使用它们的代码可以访问定义的struct
,或因此给会员.
编辑:在回答评论中的问题时,"有没有办法创建一个复杂的常量变量并将其初始化为另一个现有的同一类型常量变量的值?",确实存在 - 只需正常初始化它:
struct mystruct { const int a; const int b; }; static const struct mystruct m = {1, 2}; int main(void) { struct mystruct n = m; return 0; }
显然,你越复杂struct
,它就越复杂.
您只能const
在定义变量时初始化变量.创建一个包含const
成员的数组,将其发送到函数,然后尝试分配给这些成员,这意味着您const
首先并不是真正的意思.C中没有" const
除第一次分配外"的语法.
一个合理的替代方法是创建一个opaque类型,将定义封装在一个单独的转换单元中,然后纯粹通过函数接口访问所有成员.这样,即使事情可能不存在const
,它们仍然无法更改(除非通过故意的颠覆,这至少不比不首先调用事物const
好),因为没有使用它们的代码可以访问定义的struct
,或因此给会员.
编辑:在回答评论中的问题时,"有没有办法创建一个复杂的常量变量并将其初始化为另一个现有的同一类型常量变量的值?",确实存在 - 只需正常初始化它:
struct mystruct { const int a; const int b; }; static const struct mystruct m = {1, 2}; int main(void) { struct mystruct n = m; return 0; }
显然,你越复杂struct
,它就越复杂.