2016-02-19 3 views
-3

У меня есть функция, которая возвращает ноль в случае успеха, или номер строки, где была обнаружена ошибка:C++ Внешне видимый Const

int func() { 
    // stuff 
    if (something is wrong) { 
     return __LINE__; 
    } 
    // more stuff 
    if (something else is wrong) { 
     return __LINE__; 
    } 
    // all good 
    return 0; 
} 

Реальные абоненты только проверить, является ли возвращаемое значение равно нулю или нет, часто, как это :

int ret = func(); 
if (ret != 0) { 
    return ret; 
} 

Однако, во время тестов я хотел бы проверить фактическое возвращаемое значение, чтобы убедиться, что определенный сбой условие было вызвано:

int ret = func(); 
EXPECT_EQ(42, ret); 

Это создает проблему, так как при редактировании исходного файла func() строки возвращаемых операторов и, следовательно, возвращаемые значения также изменяются. Я хотел бы, чтобы номера строк были доступны для вызывающих абонентов func().

можно «экспортировать» номера строк, как это:

// header 
extern const int line_number; 

// source 
const int line_number = __LINE__; 

К сожалению, это работает только для номеров строк за пределами функции. Я хотел бы что-то вроде этого:

if (something is wrong) { 
    const int line_number = __LINE__; return __LINE__; 
    // or some other const thing 
} 

, который может быть прочитан из другой единицы перевода (файла).

Я попытался static const int line = __LINE__, но имеет два недостатка:

  • это не определение line_number объявлена ​​в заголовке.
  • не может быть установлен до тех пор, пока выполнение не пройдет над ним.
+1

C не C++ не является C! Не добавляйте теги для несвязанных языков. – Olaf

+0

Если вам нужны коды возврата, возвращение значения «enum» будет возможным решением вместо номеров строк. – crashmstr

+1

Почему бы не перечислить типы сбоев и не вернуть значение «enum» ошибки. Это отделяет отчет об ошибках от конфигурации файла. – NathanOliver

ответ

0

Вот пример того, как я бы решить эту проблему легко:

struct FuncErrorCodes { 
    enum Type { 
     OK = 0, 
     SOMETHING_IS_WRONG, 
     SOMETHING_ELSE_IS_WRONG, 
     ... 
    }; 
}; 

typedef FuncErrorCodes::Type FuncErrorCode; 

FuncErrorCode func() { 
    // stuff 
    if (something is wrong) { 
     return FuncErrorCodes::SOMETHING_IS_WRONG; 
    } 
    // more stuff 
    if (something else is wrong) { 
     return FuncErrorCodes::SOMETHING_ELSE_IS_WRONG; 
    } 
    ... 
    // all good 
    return FuncErrorCodes::OK; 
} 

Я не вижу никаких причин, почему я хотел бы использовать __LINE__ коды ошибок.

В обычном случае коды возврата могут все еще быть проверены на 0 (или еще лучше FuncErrorCodes::OK), и я бы без тестирования проблем для конкретных причин ошибок, как, например:

FuncErrorCode rc = func(); 
EXPECT_EQ(FuncErrorCodes::SOMETHING_IS_WRONG, ret); 

EDIT: Обратите внимание, что даже если вам удалось экспортировать «последнюю строку, установленную в код ошибки», это никоим образом не поможет, потому что это будет точное значение, возвращаемое функцией (так что вы уже знаете это). Для его фактической работы вам потребуется отдельная переменная для каждой возможной строки ошибки, которая затем будет содержать номер конкретной строки (чтобы ее можно было проверить на код возврата функции, чтобы увидеть, произошла ли конкретная ошибка).

I.e. вам нужно будет что-то вроде:

extern int something_wrong_line_number; 
extern int something_else_wrong_line_number; 

if (something is wrong) { 
    something_wrong_line_number = __LINE__; return __LINE__; 
} 

if (something else is wrong) { 
    something_else_wrong_line_number = __LINE__; return __LINE__; 
} 

// etc. - but it will of course still not work entirely well because the __LINE__ is only assigned if the error actually happens 

И это не то ничем не отличается от предоставления только простые коды ошибок для каждой конкретной ситуации ошибки, как я полагаю (и это гораздо сложнее).

Смежные вопросы