我正在使用这些gcc
标记编译我的程序:-std=c11 -Wall -Wextra -pedantic
。
我正在尝试使用带有字段标签的初始化程序初始化结构,而不是记住每个字段的正确顺序。但是我收到一些我不明白的警告。在另一个问题中,有人声称这可能是gcc
错误......我不知道这个。
这是我的代码。我尝试使用冒号:
表示法但我得到了一个过时的初始化程序警告,所以我切换到点.
表示法。
它真的只是一个错误,或者我在这里做错了什么?我可以压制这个警告,但我当时认为它不应该在那里。我仔细检查了我的代码,应该是正确的,对吗?编译器应该很开心,不要发出警告。
如果我弄错了,或者我忘记了什么,请告诉我。
编辑:我试图做的“事情”是C11
标准与否?
Can I 'extend' a struct in C?
编辑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
es3.c :
/**
* 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)
每个变量的初始值设定项都存在,但仍然显示missing initializer
gcc输出:
$ 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 version 4.9.3 (GCC)
上使用Cygwin64
。
我发现了可能的相关问题,但没有解决我的问题:
答案 0 :(得分:2)
一个未命名的成员,其类型说明符是一个没有标记的结构说明符,称为匿名结构;一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合。匿名结构或联合的成员被视为包含结构或联合的成员。如果包含的结构或联合也是匿名的,则递归应用。
我们似乎都误读了这一点(谢谢,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;
尽管如此,我们只能得出结论,如果我们可以找到建议您的编译器支持C11的文档,那么您的编译器支持C11。唉,当我遇到另一个与C11相关的问题时,我试图找到这样的文档,而且Cygwin似乎没有记录任何C11支持。如果您需要C11支持,则可能需要考虑在Windows上使用llvm / clang。
答案 1 :(得分:0)
解决了我的标题代码问题。
我尝试做的不是标准,而是针对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
参考:https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html