打印返回的结构体的成员
我在打印从函数返回的结构成员时遇到问题:
#include <stdio.h>
struct hex_string
{
char a[9];
};
struct hex_string to_hex_string_(unsigned x)
{
static const char hex_digits[] = "0123456789ABCDEF";
struct hex_string result;
char * p = result.a;
int i;
for (i = 28; i >= 0; i -= 4)
{
*p++ = hex_digits[(x >> i) & 15];
}
*p = 0;
printf("%s\n", result.a); /* works */
return result;
}
void test_hex(void)
{
printf("%s\n", to_hex_string_(12345).a); /* crashes */
}
to_hex_string_
内的 printf
调用打印正确的结果,但 printf
code> 在 test_hex
内调用使我的程序崩溃。到底是为什么呢?是一生的问题还是其他什么问题?
当我将 printf
调用替换为 puts(to_hex_string_(12345).a)
时,出现编译器错误:
invalid use of non-lvalue array
这是怎么回事?
I'm having trouble printing a member of a struct that is returned from a function:
#include <stdio.h>
struct hex_string
{
char a[9];
};
struct hex_string to_hex_string_(unsigned x)
{
static const char hex_digits[] = "0123456789ABCDEF";
struct hex_string result;
char * p = result.a;
int i;
for (i = 28; i >= 0; i -= 4)
{
*p++ = hex_digits[(x >> i) & 15];
}
*p = 0;
printf("%s\n", result.a); /* works */
return result;
}
void test_hex(void)
{
printf("%s\n", to_hex_string_(12345).a); /* crashes */
}
The printf
call inside to_hex_string_
prints the correct result, but the printf
call inside test_hex
crashes my program. Why exactly is that? Is it a lifetime issue, or is it something else?
When I replace the printf
call with puts(to_hex_string_(12345).a)
, I get a compiler error:
invalid use of non-lvalue array
What's going on here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C 中有一条很少生效的规则,它指出:
在这种情况下,在计算
printf()
的参数之后、printf()
之前有一个序列点code> 函数本身执行。您传递给printf()
的指针是一个指向返回值本身的元素的指针 - 当printf()
尝试访问字符串穿过该指针,你就会崩溃。这个问题很难遇到,因为函数值不是左值,因此您不能直接使用
&
获取指向它的指针。There is a rule in C which seldom comes into effect, which states:
In this case, there is a sequence point after the arguments to
printf()
are evaluated and before theprintf()
function itself executes. The pointer you pass toprintf()
is a pointer to an element of the return value itself - and whenprintf()
tries to access the string through that pointer, you get your crash.This issue is hard to run into, because a function value isn't an lvalue so you can't directly take a pointer to it with
&
.您已经成功地遇到了该语言的一个相当晦涩的角落案例。
在大多数情况下,数组类型的表达式会隐式转换为指向数组第一个元素的指针;例外情况是当表达式是一元
&
运算符的操作数时,当它是一元sizeof
运算符的操作数时,以及当它是所使用的初始值设定项中的字符串文字时初始化一个数组对象。这些例外情况均不适用于此处。但该转换中有一个隐含的假设:指针指向数组 object 的第一个元素。
大多数数组表达式(实际上几乎所有数组表达式)都引用某个数组对象,例如声明的数组变量、多维数组的元素等等。函数无法返回数组,因此您无法以这种方式获取非左值数组表达式。
但正如您所见,函数可以返回包含数组的结构体,并且没有与数组表达式
to_hex_string_(12345).a
关联的对象。新的 ISO C11 标准通过在描述存储持续时间的部分添加新的措辞来解决这个问题。 N1570 草案,第 6.2.4p8 节,说:
实际上,这表明函数的返回值(与大多数函数结果不同)是临时对象的值,允许其数组成员的衰减为您提供(临时)有效的指针。
但是,在编译器完全支持新的 C 标准(几年后)之前,您只需避免引用返回结构的数组成员即可。
You've managed to run into a fairly obscure corner case of the language.
An expression of array type, in most contexts, is implicitly converted to a pointer to the first element of the array; the exceptions are when the expression is the operand of a unary
&
operator, when it's the operand of a unarysizeof
operator, and when it's a string literal in an initializer used to initialize an array object. None of these exceptions applies here.But there's an implicit assumption in that conversion: the pointer is to the first element of the array object.
Most array expressions -- almost all of them, in fact -- refer to some array object, such as a declared array variable, an element of a multidimensional array, and so forth. Functions can't return arrays, so you can't get a non-lvalue array expression that way.
But as you've seen, a function can return a struct that contains an array -- and there's no object associated with the array expression
to_hex_string_(12345).a
.The new ISO C11 standard addresses this by adding new wording to the section describing storage durations. The N1570 draft, section 6.2.4p8, says:
In effect, this says that the returned value from your function (unlike most function results) is the value of a temporary object, allowing the decay of its array member to give you a (temporarily) valid pointer.
But until compilers fully support the new C standard (which won't be for some years), you'll just have to avoid referring to array members of returned structures.
您面临的问题是:返回的变量
result
是函数 _to_hex_string 的局部变量,这意味着它在函数调用结束时被删除。因此,当您尝试在test_hex
功能中检查它时,它不再可用。要解决您的问题,您可以处理指针。
这是你的代码修改,
今天过得愉快吗
The problem you're facing is that : the variable
result
which is return is a local variable of the function _to_hex_string, that's means it is deleted at the end of the fonction call. so when you try to check it in the fonctiontest_hex
it is no available any more.To solve your problem you can deal with pointer.
here is your code modify
Have I nice day