Tag: language lawyer

一个类与结构的内存布局如何

我来自C编程,其中结构中的数据首先是top变量,然后是第二个,第三个,依此类推。 我现在用C ++编程,而我正在使用类。 我基本上想要实现相同的目标,但我也想要获取/设置方法,也可能需要其他方法(我也想尝试以C ++方式实现它,并且可能会学到新东西)。 是否有保证,例如公共变量将首先在内存中,然后是私有变量?

通过联合键入C和C ++中的结构

我用gcc和g ++编译了这个迂腐,我不会在任何一个中得到警告: #include #include #include struct a { struct a *next; int i; }; struct b { struct b *next; int i; }; struct c { int x, x2, x3; union { struct aa; struct bb; } u; }; void foo(struct b *bar) { bar->next->i = 9; return; } int main(int argc, char *argv[]) { […]

按位运算符可以有未定义的行为吗?

按位运算符( ~ , & , |和^ )对其提升的操作数的按位表示进行操作。 这样的操作会导致不确定的行为吗? 例如, ~运算符在C标准中以这种方式定义: 6.5.3.3一元算术运算符 ~运算符的结果是其(提升的)操作数的按位补码(也就是说,当且仅当未设置转换的操作数中的相应位时,才设置结果中的每个位)。 整数提升在操作数上执行,结果具有提升类型。 如果提升类型是无符号类型,则表达式~E等于该类型中可表示的最大值减去E 在所有体系结构中, ~0产生一个位模式,符号位设置为1 ,所有值位设置为1 。 在一个补码架构上,该表示对应于负零。 这个位模式可以成为陷阱表示吗? 是否存在涉及更常见架构的简单位运算符的未定义行为的其他示例?

序列点和评估顺序

我正在通过K&R阅读,我在评估表达式时遇到了关于行为不确定性的这个例子,如a[i]=i++ ; 6.5美元的C99规格说明了这一点 在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。 此外,先前的值应该是只读的,以确定要存储的值。 上述K&R的例子在第一个声明中表现良好。 请解释一下如何在第二次失败。 标准是否涉及在涉及序列点的情况下子表达式的评估顺序。 例如。 a[i++] || b[i++] a[i++] || b[i++] 。 我知道这些是从左到右进行评估的,但是如何从上述声明中得出这个或者在标准中明确说明了什么呢?

严格别名和叠加inheritance

考虑以下代码示例: #include typedef struct AA; struct A { int x; int y; }; typedef struct BB; struct B { int x; int y; int z; }; int main() { B b = {1,2,3}; A *ap = (A*)&b; *ap = (A){100,200}; //a clear http://port70.net/~nsz/c/c11/n1570.html#6.5p7 violation ap->x = 10; ap->y = 20; //lvalues of types int and […]

不完整的arrays类型?

当我用gcc -Wall -pedantic -ansi -std=c89编译下面的代码时,它成功编译而没有在指针赋值时给出错误。 请注意,我将int (*)[4]为int (*)[] 。 int arr[4]; int (*p_arr)[] = &arr; 假设有一些理由允许这个(不兼容的?)赋值,当我尝试使用它时,编译器会给出不完整的类型错误error: invalid application of ‘sizeof’ to incomplete type ‘int[]’ 。 (void) sizeof(*p_arr); 这个错误让我想到允许前一个指针赋值p_arr = &arr的用途是什么? 是否按照标准允许此分配? 我使用了不完整的struct / union类型(通常用于前向声明),并且还遇到了错误incomplete array element type 。 但这种incomplete array type对我来说是新的。 是否有可能在C标准中有一个用例?

取消引用包含对象地址(数组数组)的出界指针

对于不同的REF值,以下是否定义明确? #include #define REF 1 #define S 1 int main(void) { int a[2][S] = {{1},{2}}; int *q = REF ? a[1] : 0; int *p = a[0] + S; memcpy (&q, &p, sizeof q); printf (“q[0] = %d\n”, q[0]); return 0; } 注意, p指向a[0]的最后一个元素之后,而不指向数组a[0]的元素,因此不能解引用。 但存储在p中的地址a[1][0]的地址。 p语义(故意?)指向“到”(嗯,出) a[0] 但物理上指向a[1] 。 当原始物理上只有一个指针的位模式的副本可以在语义上指向一个对象吗? 也可以看看 我用不同的“角度”问了基本相同的C / C ++问题: […]

取消引用50%的出界指针(数组数组)

这是我的“我不理解C和C ++中的指针”集合中的一个新问题。 如果我将具有相同值的两个指针的位混合(指向相同的存储器地址),那恰好具有完全相同的位表示,当一个是可解除引用且一个是结束时,标准说应该发生什么? #include #include #include // required: a == b // returns a copy of both a and b into dest // (half of the bytes of either pointers) int *copy2to1 (int *a, int *b) { // check input: // not only the pointers must be equal assert (a == b); // also the […]

这些空指针,还是地址为0的指针?

如果我写 int zero = 0; void *p1 = (void *)0; void *p2 = (void *)(int)0; void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0); void *p4 = (void *)zero; // For reference, this is a pointer to address zero void *p5 = 0; // For reference, this is a null […]

Linux内核的__is_constexpr宏

Linux Kernel的__is_constexpr(x)宏如何工作? 它的目的是什么? 什么时候介绍? 为什么要介绍? /* * This returns a constant expression while determining if an argument is * a constant expression, most importantly without evaluating the argument. * Glory to Martin Uecker */ #define __is_constexpr(x) \ (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) 有关解决相同问题的不同方法的讨论 ,请参阅: 检测宏中的整数常量表达式