- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
基于 http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ 中的建议一段时间以来,我一直在使用我自己的断言版本(称为 emp_assert
)。因此,当设置 NDEBUG 时,我的断言如下所示:
#define emp_assert(EXPR) ((void) sizeof(EXPR) )
此定义确保 EXPR 中的任何变量在编译器中仍算作“已使用”,但不会影响运行时性能。
不幸的是,我最近发现在断言中使用 lambda 会产生编译错误,因为 lambda 不能放入 sizeof。
我的选择似乎是:
选项 1 目前是我的首选,但我将此断言系统用于许多项目,并且可能会在未来一段时间内遇到问题。
选项 2 似乎太局限了,尤其是因为我可以想象 future 的意外互动。
选项 3 将是最优雅的直接解决方案,但我可以借助帮助来想出如何实现它的想法。
编辑:这里有一些示例代码来说明问题。
#include <iostream>
#include <algorithm>
#include <vector>
#define NDEBUG
// Relevant excerpt from "emp_assert.h"
#ifdef NDEBUG
#define emp_assert(EXPR) ((void) sizeof(EXPR))
#else
#define emp_assert(EXPR) \
do { if ( !(EXPR) ) { \
std::cerr << "Assert Error (In " << __FILE__ \
<< " line " << __LINE__ \
<< "): " << #EXPR << std::endl; \
abort(); } \
} while (0)
#endif
// Code to trigger the problem (asserting that all ints in a vector are less than 8.)
int main()
{
std::vector<int> v = {1, 2, 3, 4, 8};
emp_assert( std::all_of(v.begin(), v.end(), [](int i){return i < 8;}) );
}
注释掉 #define NDEBUG
以查看代码如何正确编译并在运行时触发断言。 (如果您不想断言失败,请从 vector 中删除 8)。
我使用 g++ -std=c++11 file.cc
编译
最佳答案
我相信我找到了解决方案。由于未计算的操作数中不允许使用 lambda 表达式,但常量表达式的未计算部分中允许使用 lambda 表达式,因此我们应该能够利用这一事实。
具体来说,当 NDEBUG 开启时,我将我的#define 设置为:
#define emp_assert(EXPR) { \
constexpr bool __emp_assert_tmp = false && (EXPR); \
(void) __emp_assert_tmp; \
}
constexpr
确保表达式的其余部分在编译时求值。然而,false && (EXPR)
短路,因此 EXPR 永远不会计算,但其中的变量不会被视为未使用。
变量 __emp_assert_tmp
是在它自己的范围内创建的,因此多个断言不会冲突。高度具体的名称将确保我们不会意外隐藏 EXPR 中使用的变量。任何合理的优化编译器都应该完全删除额外的变量,所以我认为它不会导致优化问题。
在我的测试中,EXPR 中的任何内容都没有执行,lambda 没有使它出错,一切似乎都在正常工作。
如果您发现我遗漏的任何问题,请告诉我。
关于c++ - 如何在没有 sizeof 的情况下最好地防止自定义断言中出现未使用的变量警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30919802/
这个问题已经有答案了: Why isn't sizeof for a struct equal to the sum of sizeof of each member? (13 个回答) 已关闭 8
先生。 Stroustrup 在他的新书(TCPL 第 4 版)第 149 页写下了以下内容 1 N && sizeof(long)<=N任何 N 值的实现,更不用说任何人都会考虑使用 wchar_t
如 [5.3.3/3] 所述(expr.sizeof,工作草案): The sizeof operator can be applied to a pointer to a function, but
从C标准来看,int至少有16bit,long至少有32bit,long long如果有的话至少有64bit(有些平台可能不支持)。只是想知道标题中的句子是否总是正确的。 最佳答案 没有。该标准仅定义
我运行的是 Windows 7(64 位)。 这个问题与此处找到的问题相同: long on a 64 bit machine 但更深入,因为它处理更多的数据类型并适用到 C 或 C++,而不是 C#
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 8年前关闭。 Improve this
这个问题在这里已经有了答案: Length of array in function argument (9 个回答) 关闭 9 年前。 #include void printS(char []);
我承认这三个都有不同的含义。但是,我不明白这些具体情况适用于哪些特定情况。任何人都可以分享每个例子吗?谢谢。 malloc(sizeof(int)) malloc(size
To avoid things quietly breaking if you change the array size, I suggest std::copy(a, a + sizeof(a)/
我在 python 中注意到以下事实: >>> (1, 2, 3).__sizeof__() 48 >>> [1, 2, 3].__sizeof__() 64 我理解列表和元组之间的区别,但我希望它们
是否存在与指针大小相同的整数类型?保证所有微架构? 最佳答案 根据 this Wikipedia page ,在 C99 中,您的 stdint.h header 可能声明了 intptr_t 和 u
我注意到 int 和 double 的大小与使用函数 MPI_Type_size(MPI_INT, &MPI_INT_SIZE); 计算的不同。这是否意味着 sizeof(MPI_INT) 返回了错误
这个问题已经有答案了: How to find the size of an array (from a pointer pointing to the first element array)? (
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
我是一名优秀的程序员,十分优秀!