2016-08-23 68 views
0

我在C.指针在结构常数字符串

header1.h写我声明指针到恒定串(的char恒定阵列),新型带struct和这种类型的可变和另一个变量:

const char *str_ptr = "Hello world!"; 

struct entry_t { 
const char *text; 
int var; 
}; 
typedef entry_t entry; 

extern entry start_entry; 

int a; 

在文件func.c我定义了新的变量:

#include "header1.h" 

entry start_entry = {str_ptr, a}; 

void func(void) 
{ 
    //here i use start_entry 
} 

但是,编译举报我电子RROR

恒定表达所需

参照的start_entry的初始化,特别是const char*构件的。 为什么?错误在哪里?

当然,如果我定义字符串作为

const char str[] = "Hello world!"; 

然后entry变量

entry start_entry = {&str, a}; 

一切正常。

EDIT_1

我在报告我的代码做了两个错误:

  1. var为const

    结构entry_t { 为const char *文本; const int var; };

  2. 在func.c 进入const

    常数项start_entry;

EDIT_2

我不在乎VAR的,我关心的是const char *成员(即使也许问题是相同的:我之前写的代码错误,还与int var我有一个错误...)。 我要重新定义一切:

//header1.h 

const char *str_ptr = "Hello world!"; 

struct entry_t { 
const char *text; 
}; 
typedef entry_t entry; 

extern const entry start_entry; 


//func.c 
#include header1.h 

const entry start_entry = {str_ptr}; 

void func(void) 
{ 
    //here i use start_entry 
} 

我不明白为什么start_entryconst char*成员,我有const char*定义它,但有这个错误。

+0

看起来您正在使用C++编译器。在C中,在源代码中没有单独定义'entry_t'。 – pmg

+0

请提供一个最小的,完整的和可验证的例子:http://stackoverflow.com/help/mcve –

+0

我敢打赌你正在使用非gcc编译器吗?你能告诉我们你正在使用哪种编译器吗? –

回答

0

问题是,使用C编译器,您不能在全局范围内初始化这些语句,它会被视为函数外的代码: (与您无法调用函数以获取该返回值并初始化全球功能外)

entry start_entry = {str_ptr, a}; 

str_ptr是不是真的认为是C的恒温,因为它被看作是一个指针。 const限定符在此处不做任何事情。

(这个问题也会发生我a顺便说一句,它看起来你正在使用一些奇怪的C++编译器或特殊的C99选项见PMG评论)

当简单地调用g++,你的榜样工程。

注意你的“自然”语句

entry start_entry = {&str, a}; 

编译(与你的编译器gcc仍然拒绝它,因为a),但因为你通过指针的地址,没有指针本身=>未指定的行为:不好。

如果你想这样做,我建议你使用C++编译器。

什么用简单的GCC调用工作:

char str_ptr[] = "Hello world!"; 
entry start_entry = {str_ptr, 12}; // considered as an array, value decided by the compiler, even if const keyword is missing 

什么不

const char *str_ptr = "Hello world!"; 
entry start_entry = {str_ptr, 12}; // str_ptr is considered as a variable pointer even if const 

entry start_entry = {"Hello world!", a}; // a is a variable: nocantdo 

如果你是对的是char []告诉编译器指针是恒定的,即使没有const关键字顺便说一句,而const关键字不考虑。

注:

我不得不修复您的代码,以便它与我的GCC编译器编译:

typedef struct { 
const char *text; 
int var; 
} entry; 

extern entry start_entry; 

的另一点是:避免在头文件中声明全局变量,你会得到多个夹杂物或未定义符号如果你有多个代码文件包括它。

+1

“char []告诉编译器该指针是常量” - 不,没有涉及的指针 –

+0

“entry start_entry = {&str,a}; 有效,但并不像您期望的那样,因为您传递的是*地址*指针,而不是指针本身!“ “ - * str *没有被定义为一个指针,所以我不应该将它的地址传递给* start_entry *的指针? – BzFr

+0

@BzFr'entry start_entry = {&str,a};'不起作用,它是一个约束冲突 –

0

您只能在初始化器中使用编译时常量。变量str_ptr甚至不是运行时常量。 const限定符的作用是防止修改指向str_ptr的字符串。指针本身可以重新分配。因此,您需要在初始化函数中初始化您的启动项:

#include "header1.h" 

entry start_entry; 

void func(void) 
{ 
    //here i use start_entry 
} 


void init(void) 
{ 
    start_entry.text = str_ptr; 
    start_entry.var = a; 
} 
+0

或者最好只是使用一个数组而不是无用的指针变量 –

+0

这种init代码应该被高度地忽视,因为它很少是线程安全的并且增加了不必要的运行时间成本,特别是如果你修复线程安全问题 –

+0

但是如果start_entry是'const',就像在EDIT_1中那样,我无法初始化它。 – BzFr