Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three different definitions of a function, no linker error; how can that be?

Tags:

c++

I have something which looks very impossible to me. I have three files which each seem to contain the exact same function declaration, albeit with a different definition.

inst_dp_vec2.cc:

void loadSOAFVec(InstVector &ivector,
                 const FVec &ret,
                 const Address *a,
                 int soanum,
                 int soalen,
                 string mask) {
    if (soalen == 2) {
        ivector.push_back(new LoadFVec(ret, a, string("")));
    } else {
        printf("SOALEN = %d not supported at %s:%d\n", soalen, __FILE__,
               __LINE__);
        exit(1);
    }
}

inst_dp_vec4.cc

void loadSOAFVec(InstVector &ivector,
                 const FVec &ret,
                 const Address *a,
                 int soanum,
                 int soalen,
                 string mask) {
    if (soalen == 4) {
        ivector.push_back(new LoadFVec(ret, a, string("")));
    } else if (soalen == 2) {
        ivector.push_back(new LoadHalfFVec(ret, a, soanum));
    } else {
        UNSUPPORTED_SOALEN(soalen);
    }
}

inst_dp_vec8.cc

void loadSOAFVec(InstVector &ivector,
                 const FVec &ret,
                 const Address *a,
                 int soanum,
                 int soalen,
                 string mask) {
    int mskbits = (((1 << soalen) - 1) << (soanum * soalen));
    stringstream mk;
    mk << "0x" << hex << mskbits;
    string localmask = mk.str();
    ivector.push_back(new LoadUnpackFVec(ret, a, localmask));
}

The linker command as executed from the Makefile (generated by GNU Autotools) seems to include all three compiled files:

g++ -O3 -g -DNO_HW_MASKING -DUSE_LDUNPK -DUSE_PKST -DUSE_PACKED_GAUGES
-DUSE_PACKED_CLOVER -DNO_GPREF_L1 -DNO_GPREF_L2 -DENABLE_STREAMING_STORES
-DSERIAL_SPIN -DSOALEN=8 -DVECLEN=4 -DPRECISION=2 codegen.o data_types.o
dslash.o dslash_common.o inst_dp_vec8.o inst_sp_vec16.o inst_dp_vec4.o
inst_sp_vec8.o inst_sp_vec4.o inst_dp_vec2.o inst_scalar.o -o codegen

From my knowledge of the one definition rule, this should give a linker error. Even more peculiar is that the version from inst_dp_vec8.o is not the one used, but the one from inst_dp_vec4.cc, although it appears first in the linker command line. I changed the code such that UNSUPPORTED_SOALEN throws an exception and with GDB I found that soalen = 8 is active. From what I know about the software, soalen = 8 only works with veclen ≥ 8 such that only the inst_dp_vec8.cc could contain the right definition.

My question: How can this possible link to a program that can be executed and only fails because of the explicit exception raised with UNSUPPORTED_SOALEN?

like image 284
Martin Ueding Avatar asked Feb 08 '17 17:02

Martin Ueding


People also ask

What does linker error mean?

Linker errors occur when the linker is trying to put all the pieces of a program together to create an executable, and one or more pieces are missing. Typically, this can happen when an object file or libraries can't be found by the linker. Fixing linker errors can be tricky.

What is multiple definition error in C?

What is multiple definition error in C? If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.20-Jul-2013.

How do I fix multiple definitions in main?

The main function is the entry point for the C++ program execution. The fix for the error is to scan the source files listed in the build log and remove the unwanted main routines in the respective files. We can have one definition of the main function for the project to run.

What is linker error in cpp?

Linker Errors: These error occurs when after compilation we link the different object files with main's object using Ctrl+F9 key(RUN). These are errors generated when the executable of the program cannot be generated. This may be due to wrong function prototyping, incorrect header files.


1 Answers

Because no diagnostic is required when the multiple definitions occur in multiple translation units.

From [basic.def.odr]:

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

and later

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement (6.4.1); no diagnostic required.

So you get an error if they are multiple definitions within on source module, but don't have to get them if they're in different ones.

like image 88
1201ProgramAlarm Avatar answered Sep 28 '22 01:09

1201ProgramAlarm