C和C++中未定义,未指定和实现定义的行为有什么区别?
c c++ undefined-behavior unspecified-behavior implementation-defined-behavior
为了使页面变脏(打开页表项中的脏位),我触摸页面的第一个字节,如下所示:
pageptr[0] = pageptr[0];
Run Code Online (Sandbox Code Playgroud)
但在实践中,gcc将忽略死店淘汰的陈述.为了防止gcc优化它,我重新编写语句如下:
volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;
Run Code Online (Sandbox Code Playgroud)
似乎这个伎俩有效,但有点难看.我想知道是否有任何指令或语法具有相同的效果?而且我不想使用-O0旗帜,因为它也会带来很大的性能损失.
我想为Atmel AVR微控制器编写C代码固件.我将使用GCC编译它.此外,我想启用编译器优化(-Os或-O2),因为我认为没有理由不启用它们,并且它们可能比手动编写汇编更快地生成更好的汇编方式.
但我想要一小段没有优化的代码.我想延迟函数的执行一段时间,因此我想写一个do-nothing循环只是为了浪费一些时间.不需要精确,只需等待一段时间.
/* How to NOT optimize this, while optimizing other code? */
unsigned char i, j;
j = 0;
while(--j) {
i = 0;
while(--i);
}
Run Code Online (Sandbox Code Playgroud)
由于AVR中的内存访问速度要慢得多,因此我希望i并将j其保存在CPU寄存器中.
更新:我刚刚发现UTIL/delay.h和UTIL/delay_basic.h从AVR libc库.尽管大多数情况下使用这些功能可能更好,但这个问题仍然有效且有趣.
相关问题:
例如,请考虑以下结构:
struct S {
int a[4];
int b[4];
} s;
Run Code Online (Sandbox Code Playgroud)
写作s.a[6]并期望它等于是合法的s.b[2]吗?就个人而言,我觉得它必须是C++中的UB,而我不确定C.但是,我没有找到任何与C和C++语言相关的内容.
更新
有几个答案建议确保字段之间没有填充以使代码可靠地工作的方法.我想强调的是,如果这样的代码是UB,那么填充缺失是不够的.如果它是UB,那么编译器可以自由地假设访问S.a[i]和S.b[j]不重叠,并且编译器可以自由地重新排序这样的存储器访问.例如,
int x = s.b[2];
s.a[6] = 2;
return x;
Run Code Online (Sandbox Code Playgroud)
可以转化为
s.a[6] = 2;
int x = s.b[2];
return x;
Run Code Online (Sandbox Code Playgroud)
总是回来2.
请原谅令人困惑的问题标题,但我不确定如何更清楚地表达它。
在 C 中,越界访问数组被归类为未定义行为。然而,数组元素保证在内存中连续排列,数组下标运算符是指针运算的语法糖(例如x[3] == *(x + 3))。因此,我个人希望以下代码的行为是明确定义的:
int array[10][10];
int i = array[0][15]; // i == array[1][5]?
Run Code Online (Sandbox Code Playgroud)
如果我对标准的解释是正确的,这将是未定义的行为。我错了吗?
我想确定以下程序(查找最大子数组的实现)是否泄漏内存。有没有通用的方法来确定这一点?例如使用调试器的某些功能?什么是一般策略?
struct Interval {
int max_left;
int max_right;
int sum;
};
struct Interval * max_crossing_subarray(int A[], int low, int mid, int high) {
struct Interval * crossing = malloc(sizeof(struct Interval));
int left_sum = INT_MIN;
int sum = 0;
for(int i = mid; i >= low; --i) {
sum = sum + A[i];
if(sum > left_sum) {
left_sum = sum;
crossing->max_left = i;
}
}
int right_sum = INT_MIN;
sum = 0;
for(int j = mid+1; j <= high; ++j) { …Run Code Online (Sandbox Code Playgroud) 如何在嵌入式Linux机器上运行valgrind来查找主软件中的内存泄漏?
在rcS脚本中,我运行如下:
./main_app
Run Code Online (Sandbox Code Playgroud)
如何将./main_app程序与valgrind联系起来?main_app进程永远不会终止.
我想不断将数据记录到文件中.此外,我想访问日志文件而不终止该main_app过程.我可以做telnet并可以访问日志文件.但问题是,除非处理程序关闭,我怎么能打开文件,即我不太明白哪个valgrind参数控制如何将内存泄漏记录到文件中.请帮忙!
c ×6
gcc ×3
arrays ×2
c++ ×2
optimization ×2
avr-gcc ×1
debugging ×1
implementation-defined-behavior ×1
memory ×1
memory-leaks ×1
mips ×1
struct ×1
valgrind ×1