C 可能的错误?带点表示法的结构中缺少初始值设定项
我正在使用这些C 可能的错误?带点表示法的结构中缺少初始值设定项,c,gcc,struct,initialization,c11,C,Gcc,Struct,Initialization,C11,我正在使用这些gcc标志编译我的程序:-std=c11-Wall-Wextra-pedantic 我尝试使用带有字段标签的初始值设定项初始化结构,而不是记住每个字段的正确顺序。然而,我得到了一些我不理解的警告。在另一个问题中,有人声称这可能是一个gccbug。。。我不知道 这是我的密码。我尝试使用冒号:表示法,但我收到一个过时的初始值设定项警告,所以我切换到了点表示法 这真的只是一个bug,还是我做错了什么?我可以压制这个警告,但我认为它本来就不应该在那里。我仔细检查了我的代码,它应该是正确的,
gcc
标志编译我的程序:-std=c11-Wall-Wextra-pedantic
我尝试使用带有字段标签的初始值设定项初始化结构,而不是记住每个字段的正确顺序。然而,我得到了一些我不理解的警告。在另一个问题中,有人声称这可能是一个gcc
bug。。。我不知道
这是我的密码。我尝试使用冒号:
表示法,但我收到一个过时的初始值设定项警告,所以我切换到了点
表示法
这真的只是一个bug,还是我做错了什么?我可以压制这个警告,但我认为它本来就不应该在那里。我仔细检查了我的代码,它应该是正确的,对吗?编译器应该很高兴,不要发出警告
如果我错了,或者我忘了什么,请告诉我
编辑:我想做的“事情”真的是标准的吗?
编辑2:已解决。见下面我的答案
学生/student.h:
#ifndef STUDENT_H
#define STUDENT_H
#define IDSIZE 7 + 1 // 7x char + '\0' terminator
typedef enum gender {
MALE = 'M',
FEMALE = 'F',
OTHER = 'O'
} gender_t;
typedef struct date {
short day;
short month;
int year;
} date_t;
typedef struct person {
char *firstname;
char *lastname;
date_t birthdate;
gender_t gender;
} person_t;
typedef struct student {
char id[IDSIZE];
struct person; // "extends" from struct person
} student_t;
#endif
/**
* Trying to refactor the student crazy shit stuff of a previous exercise.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "student/student.h"
void die(const char * format, ...);
int main(int argc, char **argv) {
if (argc < 2)
die("Usage: %s inputfile.txt\n", argv[0]);
puts("Ok");
student_t student = {
.id = "s184728",
.firstname = "Tommaso",
.lastname = "Ricci",
.birthdate = {
.day = 10,
.month = 7,
.year = 1992
},
.gender = MALE
};
return EXIT_SUCCESS;
}
void die(const char *format, ...) {
va_list args;
va_start (args, format);
vfprintf(stderr, format, args);
va_end (args);
exit(EXIT_FAILURE);
}
NAME= es3
BIN= bin
SRC= src
EXE:= $(BIN)/$(NAME)
INPUT= input.txt
#RM=rm -rf
#CC=gcc
OBJS:= $(BIN)/$(NAME).o
FLAGS= -std=c11 -Wall -Wextra -pedantic
all: $(EXE)
$(EXE): $(OBJS)
$(CC) $(FLAGS) $(OBJS) -o $(EXE)
$(BIN)/$(NAME).o: $(SRC)/$(NAME).c
$(CC) $(FLAGS) -c $(SRC)/$(NAME).c -o $(BIN)/$(NAME).o
.PHONY: clean
clean:
$(RM) $(EXE) $(OBJS)
.PHONY: run
run: $(EXE)
@$(EXE) $(INPUT)
$ make
cc -std=c11 -Wall -Wextra -pedantic -c src/es3.c -o bin/es3.o
src/es3.c: In function ‘main’:
src/es3.c:22:9: warning: missing initializer for field ‘lastname’ of ‘struct person’ [-Wmissing-field-initializers]
.lastname = "Ricci",
^
In file included from src/es3.c:9:0:
src/student/student.h:20:8: note: ‘lastname’ declared here
char *lastname;
^
src/es3.c:23:9: warning: missing initializer for field ‘birthdate’ of ‘struct person’ [-Wmissing-field-initializers]
.birthdate = {
^
In file included from src/es3.c:9:0:
src/student/student.h:21:9: note: ‘birthdate’ declared here
date_t birthdate;
^
src/es3.c:28:9: warning: missing initializer for field ‘gender’ of ‘struct person’ [-Wmissing-field-initializers]
.gender = MALE
^
In file included from src/es3.c:9:0:
src/student/student.h:22:11: note: ‘gender’ declared here
gender_t gender;
^
src/es3.c:19:15: warning: unused variable ‘student’ [-Wunused-variable]
student_t student = {
^
cc -std=c11 -Wall -Wextra -pedantic bin/es3.o -o bin/es3
es3.c:
#ifndef STUDENT_H
#define STUDENT_H
#define IDSIZE 7 + 1 // 7x char + '\0' terminator
typedef enum gender {
MALE = 'M',
FEMALE = 'F',
OTHER = 'O'
} gender_t;
typedef struct date {
short day;
short month;
int year;
} date_t;
typedef struct person {
char *firstname;
char *lastname;
date_t birthdate;
gender_t gender;
} person_t;
typedef struct student {
char id[IDSIZE];
struct person; // "extends" from struct person
} student_t;
#endif
/**
* Trying to refactor the student crazy shit stuff of a previous exercise.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "student/student.h"
void die(const char * format, ...);
int main(int argc, char **argv) {
if (argc < 2)
die("Usage: %s inputfile.txt\n", argv[0]);
puts("Ok");
student_t student = {
.id = "s184728",
.firstname = "Tommaso",
.lastname = "Ricci",
.birthdate = {
.day = 10,
.month = 7,
.year = 1992
},
.gender = MALE
};
return EXIT_SUCCESS;
}
void die(const char *format, ...) {
va_list args;
va_start (args, format);
vfprintf(stderr, format, args);
va_end (args);
exit(EXIT_FAILURE);
}
NAME= es3
BIN= bin
SRC= src
EXE:= $(BIN)/$(NAME)
INPUT= input.txt
#RM=rm -rf
#CC=gcc
OBJS:= $(BIN)/$(NAME).o
FLAGS= -std=c11 -Wall -Wextra -pedantic
all: $(EXE)
$(EXE): $(OBJS)
$(CC) $(FLAGS) $(OBJS) -o $(EXE)
$(BIN)/$(NAME).o: $(SRC)/$(NAME).c
$(CC) $(FLAGS) -c $(SRC)/$(NAME).c -o $(BIN)/$(NAME).o
.PHONY: clean
clean:
$(RM) $(EXE) $(OBJS)
.PHONY: run
run: $(EXE)
@$(EXE) $(INPUT)
$ make
cc -std=c11 -Wall -Wextra -pedantic -c src/es3.c -o bin/es3.o
src/es3.c: In function ‘main’:
src/es3.c:22:9: warning: missing initializer for field ‘lastname’ of ‘struct person’ [-Wmissing-field-initializers]
.lastname = "Ricci",
^
In file included from src/es3.c:9:0:
src/student/student.h:20:8: note: ‘lastname’ declared here
char *lastname;
^
src/es3.c:23:9: warning: missing initializer for field ‘birthdate’ of ‘struct person’ [-Wmissing-field-initializers]
.birthdate = {
^
In file included from src/es3.c:9:0:
src/student/student.h:21:9: note: ‘birthdate’ declared here
date_t birthdate;
^
src/es3.c:28:9: warning: missing initializer for field ‘gender’ of ‘struct person’ [-Wmissing-field-initializers]
.gender = MALE
^
In file included from src/es3.c:9:0:
src/student/student.h:22:11: note: ‘gender’ declared here
gender_t gender;
^
src/es3.c:19:15: warning: unused variable ‘student’ [-Wunused-variable]
student_t student = {
^
cc -std=c11 -Wall -Wextra -pedantic bin/es3.o -o bin/es3
每个变量的初始值设定项都存在,但仍然表示缺少初始值设定项
gcc输出:
#ifndef STUDENT_H
#define STUDENT_H
#define IDSIZE 7 + 1 // 7x char + '\0' terminator
typedef enum gender {
MALE = 'M',
FEMALE = 'F',
OTHER = 'O'
} gender_t;
typedef struct date {
short day;
short month;
int year;
} date_t;
typedef struct person {
char *firstname;
char *lastname;
date_t birthdate;
gender_t gender;
} person_t;
typedef struct student {
char id[IDSIZE];
struct person; // "extends" from struct person
} student_t;
#endif
/**
* Trying to refactor the student crazy shit stuff of a previous exercise.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "student/student.h"
void die(const char * format, ...);
int main(int argc, char **argv) {
if (argc < 2)
die("Usage: %s inputfile.txt\n", argv[0]);
puts("Ok");
student_t student = {
.id = "s184728",
.firstname = "Tommaso",
.lastname = "Ricci",
.birthdate = {
.day = 10,
.month = 7,
.year = 1992
},
.gender = MALE
};
return EXIT_SUCCESS;
}
void die(const char *format, ...) {
va_list args;
va_start (args, format);
vfprintf(stderr, format, args);
va_end (args);
exit(EXIT_FAILURE);
}
NAME= es3
BIN= bin
SRC= src
EXE:= $(BIN)/$(NAME)
INPUT= input.txt
#RM=rm -rf
#CC=gcc
OBJS:= $(BIN)/$(NAME).o
FLAGS= -std=c11 -Wall -Wextra -pedantic
all: $(EXE)
$(EXE): $(OBJS)
$(CC) $(FLAGS) $(OBJS) -o $(EXE)
$(BIN)/$(NAME).o: $(SRC)/$(NAME).c
$(CC) $(FLAGS) -c $(SRC)/$(NAME).c -o $(BIN)/$(NAME).o
.PHONY: clean
clean:
$(RM) $(EXE) $(OBJS)
.PHONY: run
run: $(EXE)
@$(EXE) $(INPUT)
$ make
cc -std=c11 -Wall -Wextra -pedantic -c src/es3.c -o bin/es3.o
src/es3.c: In function ‘main’:
src/es3.c:22:9: warning: missing initializer for field ‘lastname’ of ‘struct person’ [-Wmissing-field-initializers]
.lastname = "Ricci",
^
In file included from src/es3.c:9:0:
src/student/student.h:20:8: note: ‘lastname’ declared here
char *lastname;
^
src/es3.c:23:9: warning: missing initializer for field ‘birthdate’ of ‘struct person’ [-Wmissing-field-initializers]
.birthdate = {
^
In file included from src/es3.c:9:0:
src/student/student.h:21:9: note: ‘birthdate’ declared here
date_t birthdate;
^
src/es3.c:28:9: warning: missing initializer for field ‘gender’ of ‘struct person’ [-Wmissing-field-initializers]
.gender = MALE
^
In file included from src/es3.c:9:0:
src/student/student.h:22:11: note: ‘gender’ declared here
gender_t gender;
^
src/es3.c:19:15: warning: unused variable ‘student’ [-Wunused-variable]
student_t student = {
^
cc -std=c11 -Wall -Wextra -pedantic bin/es3.o -o bin/es3
如果我理解正确,:
符号已过时
我正在Cygwin64
上使用gcc版本4.9.3(gcc)
我发现了可能的相关问题,但没有解决我的问题:
- 指出:
类型说明符为不带标记的结构说明符的未命名成员称为匿名结构;类型说明符为不带标记的联合说明符的未命名成员称为匿名联合。匿名结构或联合的成员被视为包含结构或联合的成员。如果包含的结构或联合也是匿名的,则递归地应用
看来我们都误读了这一点(谢谢Dror K指出这一点)。代码的无标记版本应如下所示:
typedef struct student {
char id[IDSIZE];
struct { // <--- note the lack of tag here <---
char *firstname;
char *lastname;
date_t birthdate;
gender_t gender;
};
} student_t;
typedef结构学生{
字符id[IDSIZE];
struct{/解决了更改头代码的问题
我试图做的不是标准的,而是特定于gcc
(我想)的实现
这段代码现在正在运行,不再出现初始化器错误:
#ifndef STUDENT_H
#define STUDENT_H
#define IDSIZE 7 + 1 // 7x char + '\0' terminator
typedef enum gender {
MALE = 'M',
FEMALE = 'F',
OTHER = 'O'
} gender_t;
typedef struct date {
short day;
short month;
int year;
} date_t;
typedef struct student {
char id[IDSIZE];
char *firstname;
char *lastname;
date_t birthdate;
gender_t gender;
} student_t;
#endif
另请参见此处的GCC
参考资料:刚刚在普通Windows上试用了MinGW
,并且刚刚收到关于未使用的variable@Seb您的引用声明:“…其类型说明符是不带标记的结构说明符…”-据我所知,他的结构有一个标记?但是如果我在Windows上运行makefile,cmd
/MinGW
我会得到一个链接器错误LOL@DrorK.你是对的……我不知道我是怎么误读的(好吧,事实上,我是这样认为的……深夜会让我们中最好的人变得愚蠢)。谢谢!:)那么,我没有使用标准功能?:p您的原始代码没有问题。使用gcc-std=c11-pedantic errors-Wall-Wextra
编译就可以了。请注意,当涉及到指定的初始值设定项时,这是gcc中的一个缺陷/错误。我以前编写的只是一个gcc扩展,如果它不可移植,我就不这么做了我想使用它。但我同意,如果GCC支持,它不应该给出警告当你说-std=c11-pedantic时,你要求它不支持非标准扩展。你不可能两种方式都有。