编译器在编译时不需要知道值的&a
,它不需要知道函数地址的值。
想一下这样:编译器将以&a
为参数实例化你的函数模板,并生成“目标代码”(无论它用于传递给链接器的任何格式)。目标代码看起来像(当然不会,但你的想法):
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? */
[...]
如果实例f<b&>
,假设b
是另一个全球性的静态,编译器做同样的事情:
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? */
[...]
当你的代码调用调用这类原因:
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>__
哪个确切功能调用的错位功能名称进行编码。 生成的代码不取决于&a
或&b
的运行时间值。 编译器知道在运行时会出现这种情况(你这么说),这就是它所需要的。它会让链接器填充空白(或者如果您未能兑现承诺,就会对你大喊)。
为了您除了我怕我不看好constexpr规则不够熟悉,但两种编译器我有告诉我,这个功能将在运行时进行评估,其中,据他们说,使代码不符合。 (如果他们是错误的,则上面的回答是,至少,不完整的。)
template <int* p, int* pp>
constexpr std::size_t f() {
return (p + 1) == (pp + 7) ? 5 : 10;
}
int main() {
int arr[f<&a, &b>()] = {};
}
铛3.5在C++ 14个标准符合模式:
$ 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,相同模式:
$ 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>()];
来源
2015-04-25 15:34:29
Mat
在G ++,变量地址被占用的错位到函数名的变量名:http://coliru.stacked-crooked.com/a/ee352366c870c010 – dyp
@dyp有道理! – Lingxi
@dyp链接器将最终调整模板实例的二进制代码中的地址值“p”。我可以这样理解吗? – Lingxi