Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么';t my#ifndef预处理器指令在编译时是否阻止多个头包含?_C_C Preprocessor_Linkage - Fatal编程技术网

C 为什么';t my#ifndef预处理器指令在编译时是否阻止多个头包含?

C 为什么';t my#ifndef预处理器指令在编译时是否阻止多个头包含?,c,c-preprocessor,linkage,C,C Preprocessor,Linkage,编辑:解决了。感谢@Govind Pramar和@SomeWittyUsername提供的解决方案,在头文件中将常量声明为extern并在C文件中初始化它们是有效的 我正在从事这个项目: 我有一个头文件,其中包含常量(所有错误都与“aes_const.h”中定义的常量相关),需要由项目的其他模块访问,因此包含在所有上述模块中。 为了避免多重包含,我使用了#ifndef/#define预处理器指令,但在编译时出现以下错误: gcc -std=c99 -o aes.out aes_ciph_func

编辑:解决了。感谢@Govind Pramar和@SomeWittyUsername提供的解决方案,在头文件中将常量声明为extern并在C文件中初始化它们是有效的

我正在从事这个项目:

我有一个头文件,其中包含常量(所有错误都与“aes_const.h”中定义的常量相关),需要由项目的其他模块访问,因此包含在所有上述模块中。 为了避免多重包含,我使用了#ifndef/#define预处理器指令,但在编译时出现以下错误:

gcc -std=c99 -o aes.out aes_ciph_func.c aes_kexp_func.c aes_math.c main.c
usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x0): multiple definition of `AES_SUB_BOX'; /tmp/ccC4gp1r.o:(.rodata+0x0): first defined here
/usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x100): multiple definition of `INV_AES_SUB_BOX'; /tmp/ccC4gp1r.o:(.rodata+0x100): first defined here
/usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x200): multiple definition of `AES_LOG_TABLE'; /tmp/ccC4gp1r.o:(.rodata+0x200): first defined here
/usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x300): multiple definition of `AES_ALOG_TABLE'; /tmp/ccC4gp1r.o:(.rodata+0x300): first defined here
/usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x400): multiple definition of `AES_MULT_MAT'; /tmp/ccC4gp1r.o:(.rodata+0x400): first defined here
/usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x410): multiple definition of `INV_AES_MULT_MAT'; /tmp/ccC4gp1r.o:(.rodata+0x410): first defined here
/usr/bin/ld: /tmp/cc9HKLA4.o:(.rodata+0x420): multiple definition of `RCON'; /tmp/ccC4gp1r.o:(.rodata+0x420): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x0): multiple definition of `AES_SUB_BOX'; /tmp/ccC4gp1r.o:(.rodata+0x0): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x100): multiple definition of `INV_AES_SUB_BOX'; /tmp/ccC4gp1r.o:(.rodata+0x100): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x200): multiple definition of `AES_LOG_TABLE'; /tmp/ccC4gp1r.o:(.rodata+0x200): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x300): multiple definition of `AES_ALOG_TABLE'; /tmp/ccC4gp1r.o:(.rodata+0x300): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x400): multiple definition of `AES_MULT_MAT'; /tmp/ccC4gp1r.o:(.rodata+0x400): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x410): multiple definition of `INV_AES_MULT_MAT'; /tmp/ccC4gp1r.o:(.rodata+0x410): first defined here
/usr/bin/ld: /tmp/ccGpzVgH.o:(.rodata+0x420): multiple definition of `RCON'; /tmp/ccC4gp1r.o:(.rodata+0x420): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x0): multiple definition of `AES_SUB_BOX'; /tmp/ccC4gp1r.o:(.rodata+0x0): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x100): multiple definition of `INV_AES_SUB_BOX'; /tmp/ccC4gp1r.o:(.rodata+0x100): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x200): multiple definition of `AES_LOG_TABLE'; /tmp/ccC4gp1r.o:(.rodata+0x200): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x300): multiple definition of `AES_ALOG_TABLE'; /tmp/ccC4gp1r.o:(.rodata+0x300): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x400): multiple definition of `AES_MULT_MAT'; /tmp/ccC4gp1r.o:(.rodata+0x400): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x410): multiple definition of `INV_AES_MULT_MAT'; /tmp/ccC4gp1r.o:(.rodata+0x410): first defined here
/usr/bin/ld: /tmp/ccZWo13j.o:(.rodata+0x420): multiple definition of `RCON'; /tmp/ccC4gp1r.o:(.rodata+0x420): first defined here
collect2: error: ld returned 1 exit status
如果我的理解是正确的,这是由于我的标题被多次包含造成的

aes_const.h如下所示:

#include <stdint.h>

#ifndef AES_CONST_H
#define AES_CONST_H

//CONSTANTS ARE DECLARED HERE

#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#include "aes_kexp_func.h"
#include "aes_const.h"

//FUNCTIONS ARE IMPLEMENTED HERE
和我的主文件:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#include "aes_const.h"
#include "aes_ctypes.h"

#include "aes_math.h"
#include "aes_ciph_func.h"
#include "aes_kexp_func.h"

main(){/*code here*/}
#包括
#包括
#包括
#包括“aes_const.h”
#包括“aes_ctypes.h”
#包括“aes_math.h”
#包括“aes_ciph_func.h”
#包括“aes_kexp_func.h”
main(){/*此处代码*/}
我的ifndef不应该阻止这种情况发生吗?我缺少什么?

#如果ndef
是一条编译时指令。您在链接过程中遇到问题。您的每个源文件都是单独编译的,但在编译之后它们会链接在一起。所以,如果在多个源文件包含的头文件中定义了常量,则在链接过程中会发生冲突。头文件的经验法则-在那里声明数据,但不定义它。如果有需要由多个模块访问的常量,请在一个模块中定义它们,并在共享头文件中将它们声明为extern。

包括保护(包括
#ifndef#header(u NAME)和
#pragma once
表单)可防止同一头重复包含在同一翻译单元中,不是因为被多次包含在不同的TU中

您可以做的是:

  • aes_const.h
    中的常量定义替换为
    extern
    声明,如下所示:

    extern const uint8_t AES_SUB_BOX[16][16];
    
  • 在任何源文件中,完全定义全局变量:

    const uint8_t AES_SUB_BOX[16][16] = { /* your initialization here */ };
    

  • 你犯了一个简单的错误。在.h文件中声明真实数据和可能的代码。您应该只在C文件中执行此操作。在.h文件中,所有变量都应该声明为extern,它只发出符号,而不发出对象本身

    好吧,好吧,但那将是一团混乱…对不起,我累了,我忘了推动回购协议,常数被声明为extern…@SuperTotoGo不,你没有抓住重点。仅仅添加extern并不能解决问题。您仍然在头中定义了常量(您只是显式地将它们声明为extern)。您需要将定义和声明分开。将定义移到.c文件中,并将extern声明保留在.h文件中(您可以在GovindPramar答案中找到引用)哦,好的。但是将它们声明为static也起到了作用,即使与您的建议相比,这显然有点奇怪。@SuperTotoGo对于常量,您可以使用static并具有相同的功能。但是,您将获得相同静态数据的多个副本,这将有效地增加二进制大小。而且,这在概念上是不正确的。您的逻辑假定数据是共享的,而不是复制的。如果你有非常量数据,你会有不正确的功能(因为每个模块都会在自己的数据副本上运行),我会选择你的解决方案。我必须研究编译和链接是如何工作的,因为我仍然遗漏了一些要点。这也起到了作用,但将常量声明为static起了作用,它为我保存了一个文件。@SuperTotoGo:在头中声明常量
    static
    ,意味着包含头的每个单独的文件都有自己的私有常量集。这当然是可行的,但这有点浪费空间,可以通过“正确”地完成这项工作来节省空间——在一个源文件中定义一次数组,并使用在所有相关源文件中声明数组的头文件。
    const uint8_t AES_SUB_BOX[16][16] = { /* your initialization here */ };