2012-04-01 166 views
8

我正面臨我想解決的GCC警告。基本上我傳遞給一個方法一個指向局部變量的指針,在我的情況下,它是完全正確的。我明白爲什麼編譯器告訴我這是一個潛在的問題,但在我的情況下,這是好的。以臨時解決方法 - 需要的解決方法

我該如何解決它,在本地空間?編譯時通過-fpermissive會使我無法找到未來的問題。我想解決這個特定的問題,或解決它。

代碼可以在這裏找到:

#include <cstdio> 

class Integer{ 
public: 
    Integer(int i){ v = i; }; 
    int value(){ return v; }; 
private: 
    int v; 
}; 

int foo(Integer *i); 

int main() 
{ 
    foo(&Integer(12)); 
} 

int foo(Integer *i) 
{ 
    std::printf("Integer = %d\n", i->value()); 
} 

和編譯給我:

$ g++ test-reference.cpp -O test-reference 
test-reference.cpp: In function ‘int main()’: 
test-reference.cpp:15:18: error: taking address of temporary [-fpermissive] 

$ g++ --version 
g++ (Ubuntu/Linaro 4.6.3-1ubuntu3) 4.6.3 
Copyright (C) 2011 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

編輯:

使用const(如製造foo採取一個const指針,標誌着value()爲const)給出了相同的錯誤。

+0

@jalf看到墊響應,理解。在我的情況下,該變量在函數調用時的作用域上。 – elcuco 2012-04-01 08:46:54

+1

你不能將函數的簽名更改爲'int foo(const Integer & i);'? – jrok 2012-04-01 10:14:07

回答

9
Integer i(12); 
foo(&i); 

這擺脫了「採取一個臨時」的問題,這是你有什麼。你沒有傳遞一個局部變量的地址(這是上面所說的,而且在這種情況下的確如此),你正在獲取臨時地址。

顯然,如果foo試圖保住這個指針這樣或那樣的,你就會有上下行的問題。

+4

*你抓住了一個非常可疑的臨時地址。*不,它不可疑。行爲是明確的,'' 12.2/3' *臨時對象在評估完整表達式(詞法上)包含它們被創建的點時最後一步被破壞 – 2012-04-01 08:45:37

+0

它不比參考右值更危險 – Puppy 2012-04-01 08:46:28

+0

好吧,這意味着它是無效的,只是(IMO)可疑 – Mat 2012-04-01 08:47:38

3
template<typename T> const T* rvalue_address(const T& in) { 
    return &in; 
} 

在我看來,它應該是一樣的法律採取const T*const T&,但這個簡單的功能將輕而易舉地執行轉換。

+2

現在我們有MSVC將發出警告的代碼。 :-) – 2012-04-01 09:20:32

4

GCC在這種情況下是錯誤的。你的整數是一個右值並且取右值的地址是非法的。

§5.3.1 Unary operators, Section 3

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.

鏘給出了一個錯誤在這種情況下:

error: taking the address of a temporary object of type 'Integer' [-Waddress-of-temporary] 
    foo(&Integer(12)); 
     ^~~~~~~~~~~~ 
+3

GCC沒有錯,它用'error:'拒絕它,因爲它是非法的。 '-fpermissive'是一個海灣合作委員會的擴展,基本上說「是的,沒事,我知道你的意思*」。允許擴展程序執行他們喜歡的任何非標準事物,因爲它們是非標準的擴展。 – ams 2012-04-02 12:19:25

+0

除非另有說明,否則本標準要求對任何形式不良的程序進行診斷。警告是診斷。即使海灣合作委員會發布了警告*,但沒有*無視,這將不是一個符合性問題。 – 2015-07-08 16:15:59