在头文件中定义变量不会报错

Defining a variable in a header file doesn't give an error

我正在编写一些代码来测试该变量不应在头文件中定义。但是,没有任何错误。我就是想不通。

请告诉我为什么我在运行build.bat时没有出现错误。变量在头文件中定义,被两个源文件包含。

CMake项目结构为:

--build  
--include  
----module1.h  
--script  
----build.bat  
--src  
----Main.cpp  
----module1.cpp  
----CMakeLists.txt  
--CMakeLists.txt  

include/module1.h的内容是:

int a = 1;

src/module1.cpp的内容是:

#include "module1.h"

src/Main.cpp的内容是:

#include "module1.h"

根目录下CMakeLists.txt的内容为:

cmake_minimum_required(VERSION 3.0)

PROJECT(ProjectExample VERSION 0.1.0)

SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_FLAGS "-Wno-deprecated-declarations")

ENABLE_TESTING()
ADD_SUBDIRECTORY(src)

src/CMakeLists.txt的内容是:

SET(INCLUDE ${CMAKE_SOURCE_DIR}/include)

FILE(GLOB SOURCE "*.cpp")
LIST(REMOVE_ITEM SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp)

ADD_COMPILE_OPTIONS("-g")
ADD_COMPILE_OPTIONS("-Wall")
ADD_LIBRARY(hello ${SOURCE})

TARGET_INCLUDE_DIRECTORIES(hello PUBLIC "${INCLUDE}")
ADD_EXECUTABLE(main ${CMAKE_CURRENT_SOURCE_DIR}/Main.cpp)
TARGET_LINK_LIBRARIES(main hello)

script/build.bat的内容是:

@echo off
pushd .

if not exist build (
     md build
)

cd build
cmake -G"MinGW Makefiles" ..
mingw32-make.exe

popd

首先,忘记头文件。那是一种分心。本质上,问题是关于有两个定义相同名称的源文件:

// file1.cpp
int a = 1;

// file2.cpp
int a = 1;

问题是,为什么编译和链接这段代码没有报错?

技术上的答案是这样的重新定义违反了单一定义规则(ODR),违反ODR不需要诊断。

实际上,函数的重复定义会给出错误消息。 data 的重复定义有时不会。

如果幸运的话,当您 运行 时,代码会出现灾难性的失败。如果你运气不好,它会在你的整个测试过程中正常工作,并在你给你最重要的客户做演示时爆炸。