C 重命名(更合适):头保护将导致结构编译错误

C 重命名(更合适):头保护将导致结构编译错误,c,C,好的,我已经整理好了,评论给我指明了方向 感谢Jonathan Leffler关于gcc-E选项的想法,感谢Joachim Pileborg的提示,指出sl_堆栈似乎已经被定义为空的问题 我的问题是 // stack implementation using a single linked list struct sl_stack { struct sl_list* top; void (*push) (struct sl_stack* stack, int value)

好的,我已经整理好了,评论给我指明了方向

感谢Jonathan Leffler关于gcc-E选项的想法,感谢Joachim Pileborg的提示,指出sl_堆栈似乎已经被定义为空的问题

我的问题是

// stack implementation using a single linked list
struct sl_stack {
    struct  sl_list* top;
    void    (*push) (struct sl_stack* stack, int value);
    int     (*pop) (struct sl_stack* stack);
    int     (*peek) (struct sl_stack* stack);
    int     (*empty) (struct sl_stack* stack);
};
在以下行中给了我编译错误:

void (*push) (struct sl_stack* stack, int value);
告诉我它不知怎么错过了sl_堆栈定义

gcc-E给了我以下信息:

# 11 "list.h" 2





    struct sl_list {
        int value;
        struct sl_list* next;
    };




    typedef struct ;
    struct {
        struct sl_list* top;
        void (*push) (* stack);
        int (*pop) ();
        int (*peek) ();
        int (*empty) ();
    };

    struct * init_sl_stack()
指出了约阿希姆·皮勒伯格指出的问题。 我又快速浏览了一下我的文件,这让我很尴尬,但我没有注意到我的头罩定义了sl_堆栈。 愚蠢的事故,我的守卫和我的结构命名相同

但现在我很好奇为什么structsl_堆栈与sl_堆栈冲突?据我所知,我需要一个typedef使sl_堆栈被识别为struct sl_堆栈

我认为它的工作原理正好相反,sl_堆栈不会妨碍结构sl_堆栈…

这是:

struct*init_sl_stack()

应该是:


struct sl_stack*init_sl_stack()

#ifndef sl_stack
#define sl_stack
... contents of header ...
#endif
第二行定义了
sl_堆栈
,将其扩展为零。如果要写入令牌序列:

int x sl_stack = 3 sl_stack sl_stack + sl_stack 4;
int x = 3 + 4;
编译器将在
#定义
扩展后“查看”新序列:

int x sl_stack = 3 sl_stack sl_stack + sl_stack 4;
int x = 3 + 4;
每个
sl_堆栈
实例都已消失(或者更准确地说,被替换为只会导致令牌结束,这可能需要插入一个空格才能正确显示)

因此:

struct sl_stack {
成为:

struct {
void (*push)(struct * stack, int value);
在语法上有效,但定义了未命名的结构,并且:

void    (*push) (struct sl_stack* stack, int value);
成为:

struct {
void (*push)(struct * stack, int value);
(这与您在
gcc-E
输出中显示的不完全相同,但会在原始问题中产生错误消息)

解决此问题的一种方法是使用其他名称(例如
H_STACK
)作为标头保护名称。另一种是使用:

#define sl_stack sl_stack
它告诉编译器,当它看到令牌
sl_堆栈
时,应该用新的令牌
sl_堆栈
替换它。替换项在这里单独保留1,因此新令牌在此之后保持不变。通过将其自身替换,可以实现“无更改”效果,但
#ifdef
将告诉您
sl_堆栈实际上已定义



1这是对实际规则的过于简单的解释,但对于这种特殊用法来说已经足够了。

当你说“它破坏了”时,你是什么意思?编译错误?在这种情况下,请编辑问题以包含完整且未编辑的构建日志。“GCC还告诉我以前缺少一个“{”-然后在你认为错误的代码之前有一个错误。顺便说一句,结构定义应该可以正常工作。你是否有一个宏
push
,它会扩展成一些奇怪的东西?或者
value
?你是否查看了
gcc-E
的输出以查看编译器看到了什么?(我注意到指向堆栈函数版本的指针已经失去了存储值的能力,但这可能只是一个编辑问题。这与您当前的问题无关。)单独使用(一个文件中有7行代码,不需要标题),第二个结构,带函数指针的结构,编译得很干净。如果它没有为您干净地编译,那么您的编译会受到干扰。我建议查看预处理的输出,看看哪里出了问题。好的,您已经编辑了问题,说您有编译错误,但您仍然没有说wh至少有个错误。您显示的结构定义没有任何错误,错误必须在其他地方。但是,如果没有看到实际错误,就不可能说。请将实际错误添加到您的问题中。另外,请阅读并了解a是什么。这与问题中的代码有何不同?这如何解释问题意外的语法错误?我猜可能是分配有问题,这就是为什么我包含了工厂函数的代码…我只是更新了我的答案以删除多余的代码。注意