【问题标题】:C header files without #ifndef still work...why? [duplicate]没有#ifndef 的C 头文件仍然可以工作...为什么? [复制]
【发布时间】:2018-02-22 00:54:37
【问题描述】:

为什么我没有收到错误消息? 我有三个名为 DataType.h、printInt.h、printStr.h 和一个 myApp.c 的头文件。

数据类型.h

    typedef int Integer;
    typedef char String;

printInt.h

    #include "DataType.h"
    void printInt(Integer);

printInt.c

    #include "printInt.h"
    #include <stdio.h>
    void printInt(Integer number){
        printf("%d\n", number);
    }

printStr.h

    #include "DataType.h"
    void printStr(String*);

printStr.c

   #include "printStr.h"
   #include <stdio.h>
   void printStr(String *str){
       printf("%s\n", str);
   }

myApp.c

    #include "printStr.h"
    #include "printInt.h"
    Integer main(void){
        printInt(20);
        printStr("hello");

        return 0;
    }

显然,我已经包含了两次 DataType.h,并且我没有使用 #ifndef 来避免重新定义 Integer 和 String。请有人告诉我如何获取错误消息以证明指令正常工作。

   #ifndef __DATATYPE_H
   #define __DATATYPE_H
      typedef int Integer;
      typedef char String;
   #endif

不管有没有#ifndef,gcc 编译器(5.4.0 版)都不会产生任何错误信息。怎么了?

【问题讨论】:

  • #ifndef __DATATYPE_H 注意:带有前导下划线的预处理器宏名称是保留的。最好不要使用它们。
  • 为什么不只是#pragma once
  • 他们为什么不工作?它们只是声明。这些可以在不同的地方重复多次,没有问题。

标签: c


【解决方案1】:

typedef 的定义和函数原型可以根据需要多次出现。例如:

typedef int lala;
typedef int lala;

void somePrototype();
void somePrototype();

int main() {
    return 0;
}

会编译得很好:https://ideone.com/4EjfaR

尝试将函数的定义添加到头文件中。然后你会看到你得到一个重新定义错误,并且需要一个标头保护。

【讨论】:

  • 即:如果声明完全相同。
  • @Jean-FrançoisFabre 是的,在这个例子中它一直是这样,因为它来自一个包含。
  • 不一定,因为在包含时预处理器指令可能不同
  • 这在 C11 中并不严格合法,正如 Johnatan Leffer 的出色回答所暗示的 (stackoverflow.com/questions/26240370/…)
  • 好的!首先,感谢您的所有回复。我的错!我不应该以 typedef 为例(尽量使程序更小)。
猜你喜欢
  • 2016-09-15
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多