TYPE-双关语? [英] type-punning?

查看:74
本文介绍了TYPE-双关语?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好


我有一个程序,删除了不必要的细节,

看起来像这样:


-

#include< stdlib.h>

#include< stdio.h>


static int punme(void ** dat,size_t newsize)

{

void * newdat = realloc(* dat,newsize);


如果(!newdat)返回1;


* dat = newdat;


返回0;

}


int main(无效)

{

char * dat = malloc(30);

int ret = punme((void **)& dat,40);


printf(" punme return%i \ n",ret);


返回0;

}

-


我的编译器(gcc) -Wall -O3)告诉我typepun.c:19:

警告:解除引用类型 - 惩罚指针会破坏

严格别名规则。代码按预期工作,即

打印惩罚返回0.


谁是白痴?我还是编译器?


非常感谢!


Jim

解决方案

5月6日下午6:46,jjfish ... @ gmail.com写道:


大家好


我有一个程序,删除了不必要的细节,

看起来像这样:


-

# include< stdlib.h>

#include< stdio.h>


static int punme(void ** dat,size_t newsize)

{

void * newdat = realloc(* dat,newsize);


如果(!newdat)返回1;


* dat = newdat;


返回0;


}


int main(无效)

{

char * dat = malloc(30);


int ret = punme ((void **)& dat,40);


printf(punme return%i \ n,ret);


返回0;}


-


我的编译器(gcc -Wall -O3)告诉我&qu ot; typepun.c:19:

警告:解除引用类型 - 惩罚指针将破坏

严格别名规则。代码按预期工作,即

打印惩罚返回0.


谁是白痴?我还是编译器?



您(强制转换)并将char **分配给void **。 void **不像void

*。

修正了你的代码:


static int punme(void * dat,size_t newsize){

void ** tmp = dat;

void * newdat = realloc(* tmp,newsize);



你也没有释放分配的内存。


2008年5月6日星期二09: 43:53-0700,vippstar写道:


5月6日下午6:46,jjfish ... @ gmail.com写道:
< blockquote class =post_quotes>
> #include< stdlib.h>
#include< stdio.h>

static int punme(void ** dat, size_t newsize){
void * newdat = realloc(* dat,newsize);

if(!newdat)返回1;

* dat = newdat;

返回0;

}
int main(void)
{* char * dat = malloc(30);

int ret = punme((void **)& dat,40);

printf(" punme return%i \ n",ret);

返回0;}



嘿,这看起来很熟悉。 :)


>我的编译器(gcc -Wall -O3)告诉我typepun.c:19:warning:
取消引用类型惩罚指针将破坏严格别名规则。
代码按预期工作,即打印惩罚返回0.

谁是白痴?我还是编译器?



您(强制转换)并将char **分配给void **。 void **不像void

*。

修正了你的代码:


> static int punme (void * dat,size_t newsize){void ** tmp = dat;
void * newdat = realloc(* tmp,newsize);



这并不能解决问题。这只是以编译器可能不会发出警告的形式重新组织代码




问题是dat被定义为char *。你不能假装它被定义为无效*的
。语言不会让你失望。固定版本看起来好像



#include< stdlib.h>

#include< stdio.h>


static void * punme(void * dat,size_t newsize){

return realloc(dat,newsize);

}


int main(无效)

{

char * dat = malloc(30);

char * newdat = punme(dat,40); / *或直接调用realloc * /

if(newdat!= NULL)dat = newdat;

printf(punme会返回%d \ n, (newdat == NULL?1:0));

返回0;

}


j。********* @ gmail.com 写道:


大家好


我有一个程序,删除了不必要的细节,

看起来像这样:


-

#include< stdlib.h>

#include< stdio.h>


static int punme(void ** dat,size_t newsize)

{

void * newdat = realloc(* dat,newsize);


如果(!newdat)返回1;


* dat = newdat;


返回0;

}


int main(无效)

{

char * dat = malloc(30);


int ret = punme((void **)& dat,40);


printf(" punme return%i \\ n,ret;


返回0;

}

-


我的编译器(gcc -Wall -O3)告诉我typepun.c:19:

警告:解除引用类型惩罚指针会破坏

strict-aliasing规则" ;.代码按预期工作,即

打印惩罚返回0.


谁是白痴?我或编译器?

...



您在代码中执行内存重新解释。你有一个''char *''类型的左值

''dat'',它被重新解释为类型的左值
''void *''使用转换后跟解除引用''*(void **)

& dat''。一般来说,访问通过这种重新解释获得的左值会导致C中的未定义行为,除非类型是b $ b足够相似。在严格混叠模式下(由-O3暗示)GCC假定

在代码中不执行此类重新解释。这就是为什么

发出警告。


-

祝你好运,

Andrey Tarasevich


Hi all

I have a program which, with inessential details removed,
looks like this:

--
#include <stdlib.h>
#include <stdio.h>

static int punme(void** dat,size_t newsize)
{
void *newdat = realloc(*dat,newsize);

if (! newdat) return 1;

*dat = newdat;

return 0;
}

int main (void)
{
char *dat = malloc(30);

int ret = punme((void**)&dat,40);

printf("punme returns %i\n",ret);

return 0;
}
--

My compiler (gcc -Wall -O3) tells me that "typepun.c:19:
warning: dereferencing type-punned pointer will break
strict-aliasing rules". The code works as expected, ie,
prints that punme returns 0.

Who is the idiot? Me or the compiler?

Many thanks!

Jim

解决方案

On May 6, 6:46 pm, j.j.fish...@gmail.com wrote:

Hi all

I have a program which, with inessential details removed,
looks like this:

--
#include <stdlib.h>
#include <stdio.h>

static int punme(void** dat,size_t newsize)
{
void *newdat = realloc(*dat,newsize);

if (! newdat) return 1;

*dat = newdat;

return 0;

}

int main (void)
{
char *dat = malloc(30);

int ret = punme((void**)&dat,40);

printf("punme returns %i\n",ret);

return 0;}

--

My compiler (gcc -Wall -O3) tells me that "typepun.c:19:
warning: dereferencing type-punned pointer will break
strict-aliasing rules". The code works as expected, ie,
prints that punme returns 0.

Who is the idiot? Me or the compiler?

You (cast) and assign a char ** to a void **. void ** is not like void
*.
Fixed your code:

static int punme(void* dat,size_t newsize) {
void **tmp = dat;
void *newdat = realloc(*tmp, newsize);

You also don''t free the allocated memory.


On Tue, 06 May 2008 09:43:53 -0700, vippstar wrote:

On May 6, 6:46 pm, j.j.fish...@gmail.com wrote:

>#include <stdlib.h>
#include <stdio.h>

static int punme(void** dat,size_t newsize) {
void *newdat = realloc(*dat,newsize);

if (! newdat) return 1;

*dat = newdat;

return 0;

}

int main (void)
{
char *dat = malloc(30);

int ret = punme((void**)&dat,40);

printf("punme returns %i\n",ret);

return 0;}

Heh, this looks familiar. :)

>My compiler (gcc -Wall -O3) tells me that "typepun.c:19: warning:
dereferencing type-punned pointer will break strict-aliasing rules".
The code works as expected, ie, prints that punme returns 0.

Who is the idiot? Me or the compiler?

You (cast) and assign a char ** to a void **. void ** is not like void
*.
Fixed your code:

>static int punme(void* dat,size_t newsize) { void **tmp = dat;
void *newdat = realloc(*tmp, newsize);

This doesn''t fix the problem. This merely reorganises the code in a form
that the compiler may happen to not warn about.

The problem is that dat is defined as char *. You can''t pretend it''s
defined as a void *. The language doesn''t let you. A fixed version looks
like

#include <stdlib.h>
#include <stdio.h>

static void *punme(void *dat, size_t newsize) {
return realloc(dat, newsize);
}

int main (void)
{
char *dat = malloc(30);
char *newdat = punme(dat, 40); /* or call realloc directly */
if (newdat != NULL) dat = newdat;
printf("punme would have returned %d\n", (newdat == NULL ? 1 : 0));
return 0;
}


j.*********@gmail.com wrote:

Hi all

I have a program which, with inessential details removed,
looks like this:

--
#include <stdlib.h>
#include <stdio.h>

static int punme(void** dat,size_t newsize)
{
void *newdat = realloc(*dat,newsize);

if (! newdat) return 1;

*dat = newdat;

return 0;
}

int main (void)
{
char *dat = malloc(30);

int ret = punme((void**)&dat,40);

printf("punme returns %i\n",ret);

return 0;
}
--

My compiler (gcc -Wall -O3) tells me that "typepun.c:19:
warning: dereferencing type-punned pointer will break
strict-aliasing rules". The code works as expected, ie,
prints that punme returns 0.

Who is the idiot? Me or the compiler?
...

You perform memory reinterpretation in your code. You have an lvalue
''dat'' of type ''char*'', which is reinterpreted as an lvalue of type
''void*'' by using a conversion followed by a dereference ''*(void**)
&dat''. In general, accessing the lvalue obtained by such
reinterpretation causes undefined behavior in C, unless the types are
"similar enough". In strict-aliasing mode (implied by -O3) GCC assumes
that such reinterpretations are not performed in the code. This is why
it issues the warning.

--
Best regards,
Andrey Tarasevich


这篇关于TYPE-双关语?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆