结构类型的右值 [英] Rvalue of struct type

查看:59
本文介绍了结构类型的右值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

#include< stdio.h>

#include< string.h>

struct test {

char a [100];

}


funTest(void);

int main(无效)

{

printf("%s",funTest()。a);

返回0;

}


struct test funTest()

{

struct test foo;

strcpy(foo.a," Hello");

返回foo;

}

在此,我想知道如何以下表达式语句有效:

printf("%s",funTest()。a);


funTest()被评估为产生一个rvalue:类型,结构测试和

表达式funTest()。a产生一个char数组类型的右值,

转换为一个rvalue,等于指向char数组的第一个

元素的指针并传递给printf( )函数。


我的疑问是,因为funTest()。a产生一个rvalue类型,数组是
char,当我们只能为Lvalues而不是Rvalues指定

时,如何将它转换为指针类型。


希望我的问题很清楚。


预先感谢您的回复。

解决方案

SRR写道:


请考虑以下代码:

#include< stdio.h>

#include< string.h>

struct test {

char a [100];

}


funTest(void);



虽然有效,但这种风格非常糟糕。看起来你忘了一个

分号,并且期望funTest返回int,当你真的吝啬时,

make funTest返回struct test。


int main(无效)

{

printf("%s",funTest()。a);

返回0;

}


struct test funTest()

{

struct test foo;

strcpy(foo.a," Hello");

return foo;

}


在此,我想知道以下表达式语句的工作原理:

printf("%s",funTest()。a);


funTest()被评估为产生类型的右值,struct test和和

表达式funTest()。a产生一个char数组类型的右值,

转换为一个rvalue,等于指向char数组的第一个

元素的指针并传递给printf( )功能。



正确。


我的疑问是,因为funTest()。a产生一个rvalue类型,数组是
char,当我们只能为Lvalues而不是Rvalues指定

时,如何将其转换为指针类型。



指针指向一个临时的,并且在下一个序列点之后访问该临时值,或者修改它,导致未定义的

行为。 (如果您不知道序列点是什么,请询问。)


char c = funTest()。a [0]; / *有效,用''H'初始化c'* /

char * p = funTest()。a; / *有效,初始化p,指针值* /

c = * p; / *无效,访问函数调用后的结果

下一个序列点* /


funTest()。a [0] ='' H''; / *无效,修改函数调用的结果* /


char str [100];

strcpy(str,funTest()。a); / *无效,在下一个序列点之后访问函数调用'

结果* /


3月10日, 2:51?* pm,Harald van D?3k < true ... @ gmail.comwrote:


SRR写道:


考虑以下代码:

#include< stdio.h>

#include< string.h>

struct test {

?*?*?*?* char a [100];

}


funTest(void);



虽然有效,但这种风格非常糟糕。看起来你忘了一个

分号,并且期望funTest返回int,当你真的吝啬时,

make funTest返回struct test。



是的!你是对的。但是我在粘贴代码时无意中做到了。

实际上我把它输入为

struct test {

char a [100];

} funTest(void);

感谢你的评论abouy it。


>


int main(无效)

{

?*?* printf("%s",funTest) ().a);

?*?*返回0;

}


struct test funTest()

{

?*?*?*?* struct test foo;

?*?*?*?* strcpy(foo.a," Hello");

?*?*?*?* return foo;

}


在此我想知道以下表达式语句的工作原理:

printf("%s",funTest()。a);


funTest()被评估为产生类型的rvalue,struct test和

表达式funTest()。a产生一个char数组类型的右值,

转换为一个rvalue,等于指向char数组的第一个

元素的指针并传递给printf( )功能。



正确。


我的疑问是,因为funTest()。a产生一个rvalue类型,数组是
char,当我们只能为Lvalues而不是Rvalues指定

时,如何将其转换为指针类型。



指针指向一个临时的,并且在下一个序列点之后访问该临时值,或者修改它,导致未定义的

行为。 (如果您不知道序列点是什么,请询问。)



谢谢,我知道序列点的概念。一个函数Call是一个

序列点,因为在进入函数之前,所有的参数都被评估,包括所有的

效果。

因此我的代码生成作为临时存储器的未定义行为

可能不再包含所需的数据!

现在我理解为什么在编译和执行时出现运行时错误

使用Dev-CPP for Windows操作系统的代码,但它的执行情况很好用

TurboCPP for MS-Dos。

再次感谢你帮助我理解真正发生的事情。


>

char c = funTest()。a [0]; / *有效,用''H'初始化c'* /

char * p = funTest()。a; / *有效,初始化p,指针值* /

c = * p; / *无效,访问函数调用后的结果

下一个序列点* /


funTest()。a [0] ='' H''; / *无效,修改函数调用的结果* /


char str [100];

strcpy(str,funTest()。a); / *无效,在下一个序列点之后访问函数调用''s

结果* / - 隐藏引用文本 -



让我们扩展主题。这是唯一的情况,当一个类型

数组的rvalue转换为类型指针的rvalue指向使用临时存储的数组的第一个元素



还有其他任何可能吗?

预先感谢您的回复。


- 显示引用的文字 -



3月10日,2: 51?* pm,Harald van D?3k < true ... @ gmail.comwrote:


SRR写道:


考虑以下代码:

#include< stdio.h>

#include< string.h>

struct test {

?*?*?*?* char a [100];

}


funTest(void);



虽然有效,但这种风格非常糟糕。看起来你忘记了一个

分号,并期望funTest返回int,当你真的吝啬时,你需要使用
make funTest返回struct test。



int main(void)

{

?*?* printf("%s", funTest()。a);

?*?*返回0;

}


struct test funTest()

{

?*?*?*?* struct test foo;

?*?*?*? * strcpy(foo.a,Hello);

?*?*?*?* return foo;

}

< blockquote class =post_quotes>
在此我想知道以下表达式语句的工作原理:

printf("%s",funTest()。a);


funTest()被评估为产生类型的rvalue,struct test和

表达式funTest()。a产生一个char数组类型的右值,

转换为一个rvalue,等于指向char数组的第一个

元素的指针并传递给printf( )功能。



正确。


我的疑问是,因为funTest()。a产生一个rvalue类型,数组是
char,当我们只能为Lvalues而不是Rvalues指定

时,如何将其转换为指针类型。



指针指向一个临时的,并且在下一个序列点之后访问该临时值,或者修改它,导致未定义的

行为。 (如果您不知道序列点是什么,请询问。)


char c = funTest()。a [0]; / *有效,用''H'初始化c'* /

char * p = funTest()。a; / *有效,初始化p,指针值* /

c = * p; / *无效,访问函数调用后的结果

下一个序列点* /


funTest()。a [0] ='' H''; / *无效,修改函数调用的结果* /



忘了再问一个问题。

赋值的左操作数运算符应该是左值,但在

这种情况​​下它是一个右值,但编译器并没有抱怨

Lvalue required。因此,我可以得出结论,函数返回的包含

数组类型的结构从Rvalue转换为Lvalue!

(真的好笑!!)

或者是编译器依赖吗?

标准是否说明返回的值,函数

返回包含数组类型的结构?

我希望我的问题很明确。


预先感谢您的回复。


>

char str [100];

strcpy(str,funTest()。a) ; / *无效,在下一个序列点后访问函数调用'

结果* / - 隐藏引用文本 -


- 显示引用文本 -



Consider the following code:
#include <stdio.h>
#include <string.h>
struct test{
char a[100];
}

funTest( void );
int main( void )
{
printf("%s",funTest().a);
return 0;
}

struct test funTest()
{
struct test foo;
strcpy(foo.a,"Hello");
return foo;
}
In this I want to know how the following expression statement works:
printf("%s",funTest().a);

funTest() is evaluated to yield an rvalue of type, "struct test" and
the expression "funTest().a" yields an rvalue of type array of char,
which is converted to an rvalue equal to the pointer to the first
element of the char array and is passed to the printf() function.

My doubt is, since "funTest().a" yields an rvalue of type, array of
char, how can it be converted to pointer type when we can have pointer
only for Lvalues and not for Rvalues.

Hope my question is clear.

Thanks in advance for the reply.

解决方案

SRR wrote:

Consider the following code:
#include <stdio.h>
#include <string.h>
struct test{
char a[100];
}

funTest( void );

While valid, this is really bad style. It looks like you forgot a
semicolon and expect funTest to return int, when you really do mean to
make funTest return struct test.

int main( void )
{
printf("%s",funTest().a);
return 0;
}

struct test funTest()
{
struct test foo;
strcpy(foo.a,"Hello");
return foo;
}
In this I want to know how the following expression statement works:
printf("%s",funTest().a);

funTest() is evaluated to yield an rvalue of type, "struct test" and
the expression "funTest().a" yields an rvalue of type array of char,
which is converted to an rvalue equal to the pointer to the first
element of the char array and is passed to the printf() function.

Correct.

My doubt is, since "funTest().a" yields an rvalue of type, array of
char, how can it be converted to pointer type when we can have pointer
only for Lvalues and not for Rvalues.

The pointer points to a temporary, and accessing that temporary after
the next sequence point, or modifying it, results in undefined
behaviour. (If you don''t know what a sequence point is, please ask.)

char c = funTest().a[0]; /* valid, initialises c with ''H'' */
char *p = funTest().a; /* valid, initialised p with a pointer value */
c = *p; /* invalid, accessing the function call''s result after the
next sequence point */

funTest().a[0] = ''H''; /* invalid, modifying function call''s result */

char str[100];
strcpy(str, funTest().a); /* invalid, accessing the function call''s
result after the next sequence point */


On Mar 10, 2:51?*pm, "Harald van D?3k" <true...@gmail.comwrote:

SRR wrote:

Consider the following code:
#include <stdio.h>
#include <string.h>
struct test{
?* ?* ?* ?*char a[100];
}

funTest( void );


While valid, this is really bad style. It looks like you forgot a
semicolon and expect funTest to return int, when you really do mean to
make funTest return struct test.

Yes! You are right. But I did it inadvertantly while pasting the code.
Actually I typed it as
struct test{
char a[100];
}funTest( void );
Thanks for your comment abouy it.

>

int main( void )
{
?* ?* printf("%s",funTest().a);
?* ?* return 0;
}

struct test funTest()
{
?* ?* ?* ?*struct test foo;
?* ?* ?* ?*strcpy(foo.a,"Hello");
?* ?* ?* ?*return foo;
}

In this I want to know how the following expression statement works:
printf("%s",funTest().a);

funTest() is evaluated to yield an rvalue of type, "struct test" and
the expression "funTest().a" yields an rvalue of type array of char,
which is converted to an rvalue equal to the pointer to the first
element of the char array and is passed to the printf() function.


Correct.

My doubt is, since "funTest().a" yields an rvalue of type, array of
char, how can it be converted to pointer type when we can have pointer
only for Lvalues and not for Rvalues.


The pointer points to a temporary, and accessing that temporary after
the next sequence point, or modifying it, results in undefined
behaviour. (If you don''t know what a sequence point is, please ask.)

Thanks, I know the concept of Sequence Point. A function Call is a
sequence point as all the arguments are evaluated including all side
effects before entering the function.
Therefore my code produces undefined behavior as the temporary storage
may no longer contain the required data!
Now I understood why I got run time error when I compiled and executed
the code using Dev-CPP for Windows OS, but it executed well with
TurboCPP for MS-Dos.
Thanks once again for helping me understand what is really happening.

>
char c = funTest().a[0]; /* valid, initialises c with ''H'' */
char *p = funTest().a; /* valid, initialised p with a pointer value */
c = *p; /* invalid, accessing the function call''s result after the
next sequence point */

funTest().a[0] = ''H''; /* invalid, modifying function call''s result */

char str[100];
strcpy(str, funTest().a); /* invalid, accessing the function call''s
result after the next sequence point */- Hide quoted text -

Let us extend the topic. Is this the only case, when an rvalue of type
array is converted to rvalue of type pointer to the first element of
the array using temporary storage?
Any other possibility?
Thanks in advance for the reply.

- Show quoted text -



On Mar 10, 2:51?*pm, "Harald van D?3k" <true...@gmail.comwrote:

SRR wrote:

Consider the following code:
#include <stdio.h>
#include <string.h>
struct test{
?* ?* ?* ?*char a[100];
}

funTest( void );


While valid, this is really bad style. It looks like you forgot a
semicolon and expect funTest to return int, when you really do mean to
make funTest return struct test.


int main( void )
{
?* ?* printf("%s",funTest().a);
?* ?* return 0;
}

struct test funTest()
{
?* ?* ?* ?*struct test foo;
?* ?* ?* ?*strcpy(foo.a,"Hello");
?* ?* ?* ?*return foo;
}

In this I want to know how the following expression statement works:
printf("%s",funTest().a);

funTest() is evaluated to yield an rvalue of type, "struct test" and
the expression "funTest().a" yields an rvalue of type array of char,
which is converted to an rvalue equal to the pointer to the first
element of the char array and is passed to the printf() function.


Correct.

My doubt is, since "funTest().a" yields an rvalue of type, array of
char, how can it be converted to pointer type when we can have pointer
only for Lvalues and not for Rvalues.


The pointer points to a temporary, and accessing that temporary after
the next sequence point, or modifying it, results in undefined
behaviour. (If you don''t know what a sequence point is, please ask.)

char c = funTest().a[0]; /* valid, initialises c with ''H'' */
char *p = funTest().a; /* valid, initialised p with a pointer value */
c = *p; /* invalid, accessing the function call''s result after the
next sequence point */

funTest().a[0] = ''H''; /* invalid, modifying function call''s result */

Forgot to ask you one more question.
The left operand of assignment operator should be an Lvalue, but in
this case it is an rvalue, but the compiler doesn''t complain that
"Lvalue required". So can I conclude that a structure containing an
array type returned by a function is converted from Rvalue to Lvalue!
(Really funny!!)
Or is it Compiler dependent?
Does the standard say anything about the value returned by, functions
returning structure containing array type?
I hope my question is clear.

Thanks in advance for the reply.

>
char str[100];
strcpy(str, funTest().a); /* invalid, accessing the function call''s
result after the next sequence point */- Hide quoted text -

- Show quoted text -



这篇关于结构类型的右值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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