2013-01-18 53 views
4

我問了一個關於cmake和傳遞變量here的問題。我可以使它工作,但只有當我在函數中命名變量的方式與父範圍中的變量不同時,我將其稱爲函數。因此,在本質:奇怪的函數參數名稱行爲

function(strange name) 
    message(STATUS ${name}) 
    message(STATUS ${${name}}) 
endfunction() 

set(name foo) 
set(anothername foo) 
strange(name) 
strange(anothername) 

導致:

-- name (message(STATUS ${name}) for var "name") 
-- name (message(STATUS ${${name}}) for var "name") 
-- anothername message(STATUS ${name}) for var "anothername") 
-- foo (message(STATUS ${${name}}) for var "anothername") 

是不是有點不可思議?發生了什麼? 我認爲函數的行爲不應該取決於父範圍中變量的命名 - 是否應該?

任何澄清是非常感謝!

回答

6

不幸的是,CMake的語言是非常原始的。在這種情況下,局部變量的命名可能與外部作用域中具有相同名稱的變量交互。

具體而言,在兩個調用中,${${name}}分別擴展爲${name}${anothername}。前者name是使用其值的局部變量的名稱。在後者中,使用來自外部範圍的anothername

我不知道有什麼辦法解決這個問題,除了在函數接受變量名稱中使用混淆變量名稱作爲參數。

也許我們應該向CMake團隊申請${name:PARENT_SCOPE}

+1

+1一個明確的答案。不確定我會贊成你的請願,但: - )如果有的話,我更喜歡'AUTHOR_WARNING'類型的消息,警告隱藏父親的局部變量。 – Fraser

+0

感謝您的確切答案! – nandaloo

2

如果你想避免在@ Lindydancer的回答言簡意賅描述的本地範圍的問題,你可以改變你的函數爲macro

macro文檔:

注意,參數爲宏和像ARGN這樣的值不是通常CMake意義上的變量。它們是字符串替換,很像c預處理器對宏的處理。如果你想要真正的CMake變量,你應該看看函數命令。

如果更改使用macro,你的輸出變爲

-- name 
-- foo 
-- anothername 
-- foo 
+0

感謝您的額外信息。儘管如此,我不知道函數的優點是什麼,然後... – nandaloo

+0

我通常更喜歡一個函數,因爲它不會「污染」父函數中只有函數中使用的變量。 – Fraser