当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?
我已经阅读了 有关Stack Overflow RE的各种文章 :取消引用类型标记的指针错误。我的理解是,该错误本质上是编译器警告,它警告通过不同类型的指针访问对象的危险(尽管似乎为产生了例外),这是可以理解且合理的警告。 char*
我的问题特定于以下代码:为什么将指针的地址强制转换void**为此警告的合格字符(通过导致错误-Werror)?
而且,此代码针对多个目标体系结构进行了编译,只有其中一种会生成警告/错误-这是否暗示它合法地是特定于编译器版本的缺陷?
// main.c
#include <stdlib.h>
typedef struct Foo
{
int i;
} Foo;
void freeFunc( void** obj )
{
if ( obj && * obj )
{
free( *obj );
*obj = NULL;
}
}
int main( int argc, char* argv[] )
{
Foo* f = calloc( 1, sizeof( Foo ) );
freeFunc( (void**)(&f) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果上述我的理解是正确的,a void**仍然只是一个指针,这应该是安全的。
有没有不使用左值来解决此编译器特定警告/错误的解决方法?也就是说,我理解这以及为什么这可以解决问题,但是我想避免这种方法,因为我想利用 …
6.7.2.1我的C99标准草案第14段有关于工会和指针的说法(强调,一如既往地增加):
联合的大小足以容纳其中最大的成员.最多一个成员的值可以随时存储在union对象中.指向适当转换的联合对象的指针指向其每个成员(或者如果成员是位字段,则指向它所在的单元),反之亦然.
一切都很好,这意味着执行类似下面的操作将有符号或无符号的int复制到联合中是合法的,假设我们只想将其复制到相同类型的数据中:
union ints { int i; unsigned u; };
int i = 4;
union ints is = *(union ints *)&i;
int j = is.i; // legal
unsigned k = is.u; // not so much
Run Code Online (Sandbox Code Playgroud)
7.15.1.1第2段有这样的说法:
的
va_arg宏扩展到具有SPECI音响版类型和在呼叫中的下一个参数的值的表达式.该参数ap应该由va_start或va_copy宏初始化 (没有va_end为sameap 中间调用宏).每次调用va_arg宏都会修改,ap以便依次返回连续参数的值.参数type应该是一个特定的类型名称,这样只需通过后缀a*来获得指向具有指定类型的对象的指针类型type.如果没有实际的下一个参数,或者type与实际的下一个参数的类型不兼容(根据默认参数提升而提升),则行为是未定义的,除了以下情况:-one type是有符号整数类型,另一种类型是相应的无符号整数类型,并且该值可在两种类型中表示;
-one类型是指向void的指针,另一个是指向字符类型的指针.
我不打算引用关于默认参数促销的部分.我的问题是:这是定义的行为:
void func(int i, ...)
{
va_list arg;
va_start(arg, i);
union ints is = …Run Code Online (Sandbox Code Playgroud) 我有一个unsigned char指针,其中包含一个结构.现在我想要执行以下操作
unsigned char *buffer ;
//code to fill the buffer with the relavent information.
int len = ntohs((record_t*)buffer->len);
Run Code Online (Sandbox Code Playgroud)
其中record_t结构包含一个名为len的字段.我无法这样做并且收到错误.
error: request for member ‘len’ in something not a structure or union.
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?