簡體   English   中英

獲取宏中函數的返回類型(C++)

[英]Get return type of function in macro (C++)

我有ASSERT(x)宏,如果它斷言(在發布配置中),我想調用return 為此,我需要知道使用此ASSERT的函數的返回類型。 如何得到它(我處理C++03LLVM GCC 4.2編譯器)?

我的斷言宏:

#define ASSERT(x) \
    if(!(x)) {
        LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
        return /*return_type()*/; \
    }

PS:我試過return 0; - 如果return;編譯器顯示 void 函數錯誤(我沒有嘗試復雜的返回類型) return; - 非空函數的錯誤。

(更新...)

我會在這里回答werewindlenyarlathotepjdv-Jan de Vaan 我使用標准assert進行調試配置。 但是在 beta 測試之后,我仍然會收到最終客戶的崩潰報告,並且在大多數情況下,我需要更改我的崩潰函數:

ASSERT (_some_condition_);
if (!_some_condition_)      // add this return
    return _default_value_;

我知道,我的程序可能會在以后崩潰(否則它肯定會在當前函數中崩潰)。 我也不能退出應用程序,因為開發是針對 iPhone 的(應用程序可能不會在那里以編程方式退出)。 所以最簡單的方法是在斷言失敗時“自動返回”。

您無法確定宏中周圍函數的返回類型; 宏由預處理器擴展,它沒有關於這些宏出現的環境的這種信息; 它基本上只是“搜索和替換”宏。 您必須為每種返回類型編寫單獨的宏。

但為什么不退出程序(即調用exit函數)? 剛從函數返回似乎不是一個非常強大的錯誤處理。 失敗的斷言應該只在某些事情出現嚴重錯誤時發生(意味着程序處於不能設計處理的狀態),因此最好盡快退出程序

沒有正確的方法來確定C中函數內的返回類型。

此外,如果您以某種方式實現ASSERT的變體,它將導致錯誤的程序行為。 ASSERT主要思想:如果失敗,那么程序處於未定義狀態,只有正確的方法是立即停止它。 即通過調用exit()

你不能這樣做,C / C ++預處理器非常基礎,不能進行任何代碼分析。 您最多可以將返回類型傳遞給宏。

但是我的意見是:你使用錯誤的方式使用斷言。 它們只應用於代碼的健全性檢查(對於錯誤而言,只能由於程序員而發生); 如果所有斷言都通過,你不需要關心它們,你不需要記錄它們。

不僅如此,而且(一般而言)你應該使用最少驚喜的元素。 你期望ASSERT記錄一些東西然后強行讓函數返回嗎? 我知道我不會。 我要么完全關閉應用程序(標准assert做什么),要么讓我決定接下來會發生什么(也許我有一些免費的指針)。

就這樣做

#define ASSERT(x, ret, type)    \
     if(!(x)){
          LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
          return (type) ret;
     }

我相信您正在嘗試解決錯誤的問題。 你不希望你的程序在斷言的情況下崩潰,你最好改進你的測試。

在這些斷言中有“回報”會給你一種虛假的安全感。 相反,它隱藏了您的問題並導致程序中出現意外行為,因此您遇到的錯誤要復雜得多。 我的一位同事實際上寫了一篇很好的博客文章

如果你真的想要它,你可以嘗試寫return {}; 所以它默認構造值,或者有一個斷言宏,您還可以在其中提供失敗案例。 不過我真的不推薦!

宏不return值,因為它們本身不是函數。 它們替換使用它們的源代碼,因此您將return使用宏的函數。

無法從宏獲取return value

我認為您可以使用模板函數執行此操作,您可以在宏中調用default(x)。

template<class T> default<T>(T x) { return T(); }

這將適用於默認構造函數的每一個。 我認為你需要為void編寫一個特殊的宏。

我希望我的模板語法正確,我的c ++正在生銹。

您可以根據需要定義另一個宏。

#define ASSERT(x) \
    if(!(x)) { \
        LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
        ASSERT_DEFAULT_RETURN(); \
    }

然后在一個函數內:

int foo(){
#ifdef ASSERT_DEFAULT_RETURN
#undef ASSERT_DEFAULT_RETURN
#endif
#define ASSERT_DEFAULT_RETURN() return 0
  // ...
  ASSERT(some_expression);
  // ...
  // cleanup
#undef ASSERT_DEFAULT_RETURN
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM