The compiler does not need to know the value of &a at compile time more than it needs the value of the function addresses.
Think of it this way: the compiler will create your function template using &a as a parameter and generate "object code" (in whatever format it uses to pass to the linker). The code of the object will look (well it will not, but you get the idea):
func f__<funky_mangled_name_to_say_this_is_f_for_&a>__: reg0 <- reg1 <- call std::basic_stream::operator<<(int*) [...]
If you instantiate f<b&> , assuming b is another global static, the compiler does the same:
func f__<funky_mangled_name_to_say_this_is_f_for_&b>__: reg0 <- reg1 <- call std::basic_stream::operator<<(int*) [...]
And when your code calls any of them:
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>__
What exact function to call is encoded in the name of the changed function. The generated code is independent of the runtime value of &a or &b . The compiler knows that at runtime there will be such things (you said it that way) that all that is needed. This will allow the linker to fill in the blanks (or yell at you if you have not kept your promise).
For your addition, Iβm afraid that I am not well aware of the constexpr rules, but two compilers, I will say that this function will be evaluated at runtime, which, in their opinion, makes the code inappropriate, (If they are wrong, then the answer is higher, at 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 compliance mode:
$ clang++ -std=c++14 -stdlib=libc++ t.cpp -pedantic t.cpp:10:10: warning: variable length arrays are a C99 feature [-Wvla-extension] int arr[f<&a, &b>()]; ^ 1 warning generated.
GCC g ++ 5.1, the 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>()];