Принимая адрес временного - требуется обходной путь - PullRequest
8 голосов
/ 01 апреля 2012

У меня предупреждение 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) дает ту же ошибку.

Ответы [ 3 ]

9 голосов
/ 01 апреля 2012
Integer i(12);
foo(&i);

Это избавляет от проблемы «принятия адреса временной», которая есть у вас.Вы не передаете адрес локальной переменной (что вышеизложенное делает, и в этом случае это действительно нормально), вы захватываете адрес временного.

Очевидно, если foo пытаетсяудерживайте этот указатель так или иначе, у вас будут проблемы в дальнейшем.

4 голосов
/ 01 апреля 2012

GCC не так в этом случае.Ваше целое число является rvalue, и взятие адреса rvalue является незаконным.

§5.3.1 Унарные операторы, Раздел 3

Результатом унарного оператора & является указатель на его операнд.Операндом должно быть lvalue или квалифицированный идентификатор.

Clang выдает ошибку в этом случае:

error: taking the address of a temporary object of type 'Integer' [-Waddress-of-temporary]
    foo( &Integer(12) );
         ^~~~~~~~~~~~
4 голосов
/ 01 апреля 2012
template<typename T> const T* rvalue_address(const T& in) {
    return &in;
}

По моему мнению, const T* должно быть так же законно, как const T&, но эта тривиальная функция легко выполнит преобразование.

...