0

I am writing some code to test that variable shouldn't be defined in a header file. However, there isn't any error. I just can't figure it out.

Please tell me why an error does not occur when I run build.bat. The variable is defined in the header file, which is included by two source files.

The structure of the CMake project is:

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

The content of include/module1.h is:

int a = 1;

The content of src/module1.cpp is:

#include "module1.h"

The content of src/Main.cpp is:

#include "module1.h"

The content of CMakeLists.txt in the root directory is:

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)

The content of src/CMakeLists.txt is:

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)

The content of script/build.bat is:

@echo off
pushd .

if not exist build (
     md build
)

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

popd
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
fizzbuzz
  • 159
  • 1
  • 1
  • 8
  • 2
    Not used variable. – 273K Jun 27 '20 at 07:43
  • Well you don't say what the error is, but obviously if you **define** a variable in a header file, then you run the risk of multiple definition errors. The answer is to **declare** (not define) variables in header files. Do you know the difference? – john Jun 27 '20 at 08:02
  • Sorry, I mean it ought to have an error of multiple definition, but it doesn't. I just cann't figure it out. – fizzbuzz Jun 27 '20 at 08:04
  • @fizzbuzz Sorry I misread your question. SM is probably right – john Jun 27 '20 at 08:07
  • @S.M. As you said, I add the function PrintA() in module1.cpp. And in function main() in Main.cpp, PrintA() is called. Then the error Multiple definition of 'a' occured. Is it because only in this situation, external linkage happened? – fizzbuzz Jun 27 '20 at 08:31
  • It has nothing with external linkage. Modern compilers don't allocate storages for unused variables, no storages - no symbols, no multiple definitions. [Does an unused member variable take up memory?](https://stackoverflow.com/questions/55060820/does-an-unused-member-variable-take-up-memory) – 273K Jun 27 '20 at 08:41
  • Well, it depends on what `PrintA` does. If it actually prints `a`, the symbol is used and thus twicely defined (with external linkage). – Mikael H Jun 27 '20 at 09:07

1 Answers1

1

First, forget about the header file. That's a distraction. In essence, the question is about having two source files that define the same name:

// file1.cpp
int a = 1;

// file2.cpp
int a = 1;

and the question is, why doesn't compiling and linking this code give an error?

The technical answer is that such a redefinition is a violation of the one definition rule (ODR), and violations of the ODR do not require diagnostics.

In practice, having duplicate definitions of a function will give an error message. Duplicate definitions of data sometimes don't.

If you're lucky, the code will fail disastrously when you run it. If you're unlucky, it will work just fine throughout your testing, and blow up when you give a demo to your most important client.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165