c++ - Confusion about pointer values being compile-time constatns -


in c++, possible pointer values compile-time constants. true, otherwise, non-type template parameters , constexpr won't work pointers. however, far know, addresses of functions , objects of static storage known (at least) @ link-time rather compile-time. following illustration:

main.cpp

#include <iostream>  template <int* p> void f() { std::cout << p << '\n'; }  extern int a;  int main() {     f<&a>(); } 

a.cpp

int = 0; 

i'm wondering how address of a possibly known when compiling main.cpp. hope explain little me.

in particular, consider this

template <int* p, int* pp> constexpr std::size_t f() {    return (p + 1) == (pp + 7) ? 5 : 10;  }  int main() {     int arr[f<&a, &b>()] = {}; } 

how should storage arr allocated?

plus: mechanism seems rather robust. when enabled randomized base address, correct output obtained.

the compiler doesn't need know value of &a @ compile time more needs value of function addresses.

think of this: compiler instantiate function template &a parameter , generate "object code" (in whatever format uses pass linker). object code (well won't, idea):

func f__<funky_mangled_name_to_say_this_is_f_for_&a>__:    reg0 <- /* linker, pls put &std::cout here */    reg1 <- /* hey linker, stuff &a in there ok? */    call std::basic_stream::operator<<(int*) /* linker, fun addr please? */    [...] 

if instantiate f<b&>, assuming b global static, compiler same thing:

func f__<funky_mangled_name_to_say_this_is_f_for_&b>__:    reg0 <- /* linker, pls put &std::cout here */    reg1 <- /* hey linker, stuff &b in there ok? */    call std::basic_stream::operator<<(int*) /* linker, fun addr please? */    [...] 

and when code calls calling either of those:

fun foo:    call f__<funky_mangled_name_to_say_this_is_f_for_&a>__     call f__<funky_mangled_name_to_say_this_is_f_for_&b>__ 

which exact function call encoded in mangled function name. generated code doesn't depend on runtime value of &a or &b. compiler knows there such things @ runtime (you told so), that's needs. it'll let linker fill in blanks (or yell @ if failed deliver on promise).


for addition i'm afraid i'm not familiar enough constexpr rules, 2 compilers have tell me function evaluated @ runtime, which, according them, makes code non-conforming. (if they're wrong, answer above is, @ least, incomplete.)

template <int* p, int* pp> constexpr std::size_t f() {    return (p + 1) == (pp + 7) ? 5 : 10;  }  int main() {     int arr[f<&a, &b>()] = {}; } 

clang 3.5 in c++14 standards conforming mode:

$ clang++ -std=c++14 -stdlib=libc++ t.cpp -pedantic t.cpp:10:10: warning: variable length arrays c99 feature [-wvla-extension]   int arr[f<&a, &b>()];          ^ 1 warning generated. 

gcc g++ 5.1, same mode:

$ g++ -std=c++14 t.cpp -o3 -pedantic t.cpp: in function 'int main()': t.cpp:10:22: warning: iso c++ forbids variable length array 'arr' [-wvla]    int arr[f<&a, &b>()]; 

Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -