Does redefining a function from the standard library violate the one-definition rule?

前端 未结 3 2016
鱼传尺愫
鱼传尺愫 2021-01-06 00:58
#include 

double log(double) {return 1.0;}
int main() {
  log(1.0);
}

Suppose the function log() in <

3条回答
  •  [愿得一人]
    2021-01-06 01:23

    Beware. The ODR only concerns definitions that will be included in the resulting program. That means that is does not concern symbols that could be present in libraries, because a (normal) linker does not load the whole libraries, but only the parts that are required to resolve symbols. For example in this code:

    #include 
    
    double log(double) {return 1.0;}
    
    int main()
    {
        log(1.0);
    }
    

    There is no violation of the ODR:

    • either the log symbol from the C standard library was only included in the std namespace and there is no collision at all
    • or it is also included in global namespace

    In latter case, the declaration double log(double) does not conflict with the one from cmath because it is the same. And as the symbol log is already defined, its definition from the standard library will not be included in the program. As such, only one definition for the log function exists in the program, that one: double log(double) {return 1.0;}.

    Things would be different if you extracted the object module containing log from the math library and explicitely link it in your program. Because object modules are always included in the resulting program whereas object modules in libraries are only conditionaly included if they resolve undefined symbols.


    References from standard:

    Draft n3337 for C++11 or n4296 for C++14 (or n4618 for last revision) are explicit in paragraph 2.2 Phases of translation [lex.phases]:

    §9. All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment.

    As shown code uses only one translation unit and as log is already defined in it, the definition from the library will not be used.

提交回复
热议问题