小编Shi*_*zou的帖子

在逗号运算符中,如果没有副作用,左操作数是否保证不会被实际执行?

为了显示我将要使用C的主题,但是同样的宏也可以在C++中使用(有或没有struct),提出了相同的问题.

我想出了这个宏

#define STR_MEMBER(S,X) (((struct S*)NULL)->X, #X)
Run Code Online (Sandbox Code Playgroud)

它的目的是拥有const char*a的现有成员的strings()struct,这样如果该成员不存在,则编译失败.最小用法示例:

#include <stdio.h>

struct a
{
    int value;
};

int main(void)
{
    printf("a.%s member really exists\n", STR_MEMBER(a, value));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果value不是其成员struct a,代码将无法编译,这就是我想要的.

逗号运算符应该计算左操作数,然后丢弃表达式的结果(如果有的话),因此我的理解是,当左操作数的计算具有副作用时通常使用此运算符.

然而,在这种情况下,没有(预期的)副作用,但是当然如果编译器实际上没有产生评估表达式的代码,它将起作用,否则它将访问struct位于at NULL并且分段错误将发生.

Gcc/g ++ 6.3和4.9.2从未产生过那些危险的代码,即使-O0它们总是能够"看到"评估没有副作用,因此可以跳过它.

添加volatile宏(例如,因为访问该存储器地址期望的副作用)是迄今为止触发分段错误的唯一方式.

所以问题是:C和C++语言标准中有什么保证编译器总是避免在编译器可以确定评估没有副作用时对逗号运算符的左操作数进行实际评估吗?

注意和修复

我不问了一个关于宏判断,因为它和使用它或使它更好的机会.出于这个问题的目的,宏是坏的,当且仅当它引起未定义的行为 - 即,当且仅当它有风险因为允许编译器生成"评估代码",即使这没有副作用.

我已经有两个明显的修复:"reifying" struct和使用offsetof.前者需要一个可访问的内存区域,与struct我们用作第一个参数的最大内容一样大 …

c c++ standards gcc

30
推荐指数
2
解决办法
1747
查看次数

字符串或二进制数据将被截断SQL错误

我有一个SQL存储过程,它接受VARCHAR(MAX)类型的参数.据我所知,根据我读到的所有内容,这些字符串的最大大小为2GB: MSDN

出于某种原因,当传递大于8KB的字符串时,我得到:

字符串或二进制数据将被截断.

为什么我会收到此错误消息,如何解决?

sql t-sql varchar

9
推荐指数
2
解决办法
7万
查看次数

处理命令行参数

我一直在使用OpenCV,我见过的一些示例代码使用以下内容来读取文件名.我知道argc是传递的命令行参数的数量,而argv是参数字符串的向量,但有人可以澄清下一行的每个部分的作用吗?我试过搜索这个,但没有找到很多结果.谢谢.

const char* imagename = argc > 1 ? argv[1] : "lena.jpg";
Run Code Online (Sandbox Code Playgroud)

谢谢.

c++ ternary-operator command-line-arguments

2
推荐指数
1
解决办法
568
查看次数