0

I have 5 files in my project: stack.h, stack.cpp, calc.h, calc.cpp and main.cpp. I included in main.cpp - stack.h and calc.h, in calc.cpp I included stack.h and calc.h. In stack.h and calc.h i've written #pragma once. In stack.cpp I included stack.h. So, but after I build my project, i have linker error:

Ld /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Products/Debug/Calculator normal x86_64
    cd /Users/ratkke/Desktop/Calculator
    export MACOSX_DEPLOYMENT_TARGET=10.10
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -L/Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Products/Debug -F/Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Products/Debug -filelist /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/Calculator.LinkFileList -mmacosx-version-min=10.10 -stdlib=libc++ -Xlinker -dependency_info -Xlinker /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/Calculator_dependency_info.dat -o /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Products/Debug/Calculator

duplicate symbol __Z11getPriorityc in:
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/main.o
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/calc.o
duplicate symbol __Z10isOperatorc in:
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/main.o
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/calc.o
duplicate symbol __Z8isNumberc in:
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/main.o
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/calc.o
duplicate symbol __Z11getOperatorc in:
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/main.o
    /Users/ratkke/Library/Developer/Xcode/DerivedData/Calculator-esrbpuwjualqxkenoegznrxlvebi/Build/Intermediates/Calculator.build/Debug/Calculator.build/Objects-normal/x86_64/calc.o
ld: 4 duplicate symbols for architecture x86_64

And I don't get why the error is exist.

Cœur
  • 37,241
  • 25
  • 195
  • 267
ratkke
  • 469
  • 1
  • 4
  • 13

2 Answers2

0

pragma once will only hava effect on the object that you are currently compiling. Example: If main includes stack.h and calc.h and calc.h also include stack.h, you would end up having stack.h twice, once you build main.cpp if you did not use "#pragma once" (you can see that, if you stop the compilation just after the pre-processor, see here GCC preprocessor).

But pragma once has no effect on linking. Because you build main.o, stack.o and calc.o in different steps and after that you link them to an application, each object will include the functions, that you possibly added to the headers. So you are ending up with a function body of getPrity() in main.o and in calc.o.

You can declare the functions the header to be static, like this

static int getPriority() {
    return 0;
}

or you enclose them in a anonymous namespace, if you are using c++:

namespace {
    int getPriority() { 
        return 0;
    }
}
Community
  • 1
  • 1
pdx9k9e9
  • 61
  • 1
  • 2
  • I actually recommend inline instead, because static functions will have one definition per transition unit, therefore bloating the resulting compiled code massively if not optimized(Visual doesnt do this unless you actually set some flags up, and only on 2013 for instance), whereas inline will have 1 body per function – Creris Oct 20 '14 at 17:37
0

It's always better to put the function declaration in .h file and function definition in .cpp file.

So in your case put the following statement in calc.h file.

int getPriority();

And then put the function definition in calc.cpp

int getPriority() {
    // More functionality 
    return 0;
}

If function is small then you can use Inline. As explained in other answer #pragma once has no effect on linking. You have to use either inline or function declaration.

Vishal Gupta
  • 154
  • 9