我在以下程序的第6行(初始化my_foo到foo_init)上得到一个错误,我不确定我理解为什么。
typedef struct foo_t {
int a, b, c;
} foo_t;
const foo_t foo_init = { 1, 2, 3 };
foo_t my_foo = foo_init;
int main()
{
return 0;
}
请记住,这是我正在进行的一个大型多文件项目的简化版本。目标是在目标文件中有一个常量,多个文件可以使用它来初始化一个状态结构。由于它是一个资源有限的嵌入式目标,而且结构也不是那么小,所以我不想要源的多个副本。我不喜欢使用:
#define foo_init { 1, 2, 3 }
我还试图编写可移植的代码,所以我需要一个有效的C89或C99的解决方案。
这和目标文件中的组织有关系吗?初始化变量进入一个ORG,并通过复制第二个ORG的内容进行初始化?
也许我只需要改变我的策略,让一个初始化函数在启动时完成所有的复制。除非还有别的办法?
这有点老了,但我遇到过类似的问题。如果你使用指针,你可以做到这一点:
#include <stdio.h>
typedef struct foo_t {
int a; int b; int c;
} foo_t;
static const foo_t s_FooInit = { .a=1, .b=2, .c=3 };
// or a pointer
static const foo_t *const s_pFooInit = (&(const foo_t){ .a=2, .b=4, .c=6 });
int main (int argc, char **argv) {
const foo_t *const f1 = &s_FooInit;
const foo_t *const f2 = s_pFooInit;
printf("Foo1 = %d, %d, %d\n", f1->a, f1->b, f1->c);
printf("Foo2 = %d, %d, %d\n", f2->a, f2->b, f2->c);
return 0;
}
这有点老了,但我遇到过类似的问题。如果你使用指针,你可以做到这一点:
#include <stdio.h>
typedef struct foo_t {
int a; int b; int c;
} foo_t;
static const foo_t s_FooInit = { .a=1, .b=2, .c=3 };
// or a pointer
static const foo_t *const s_pFooInit = (&(const foo_t){ .a=2, .b=4, .c=6 });
int main (int argc, char **argv) {
const foo_t *const f1 = &s_FooInit;
const foo_t *const f2 = s_pFooInit;
printf("Foo1 = %d, %d, %d\n", f1->a, f1->b, f1->c);
printf("Foo2 = %d, %d, %d\n", f2->a, f2->b, f2->c);
return 0;
}
在C语言中,具有静态存储持续时间的对象必须使用常量表达式进行初始化,或者使用包含常量表达式的聚合初始化器进行初始化。
在C语言中,“大”对象从来不是常量表达式,即使对象声明为const。
此外,在C语言中,术语“常量”指的是文字常量(如1,'a', 0xFF等),枚举成员,以及sizeof等操作符的结果。const限定的对象(任何类型)在C语言术语中都不是常量。它们不能在具有静态存储持续时间的对象的初始化式中使用,无论其类型如何。
例如,这不是一个常数
const int N = 5; /* `N` is not a constant in C */
上面的N在c++中是常数,但在C中不是常数,所以,如果你试着
static int j = N; /* ERROR */
您将得到相同的错误:尝试用非常量初始化静态对象。
这就是为什么在C语言中,我们主要使用#define来声明命名常量,也使用#define来创建命名聚合初始化器的原因。
GCC 7.4.0不能编译如下代码:
#include <stdio.h>
const char * const str1 = "str1";
const char * str2 = str1;
int main() {
printf("%s - %s\n", str1, str2);
return 0;
}
conchar .c:3:21:错误:初始化元素不是常量
Const char * str2 = str1;
事实上,"const char *"字符串不是编译时常量,因此它不能是初始化项。但是"const char * const"字符串是一个编译时常量,它应该是一个初始化式。我认为这是CLang的一个小缺点。
函数名当然是一个编译时常数。所以这段代码是有效的:
void func(void)
{
printf("func\n");
}
typedef void (*func_type)(void);
func_type f = func;
int main() {
f();
return 0;
}