編譯器在編譯時不需要知道值的&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