只需在VC2008中构建并运行它:
struct A
{
int a;
int b;
int c;
};
A a = { 10, 20, 30 };
printf("%d %d %d\n", a);
这是正常的吗?
10 20 30
我想投!但它不起作用:
struct A
{
int a;
int b;
int c;
operator int()
{
return a + b + c;
}
};
A a = { 10, 20, 30 };
printf("%d\n", a);
仅输出:
10
我需要自动转换模板实用程序。 这是:https://code.google.com/p/boolib/source/browse/boolib/crypt/ShakedValue.h 它应该隐藏在内存中,任何hack-programms(ArtMoney)都找不到值。
还有一个技巧:打印struct / class的私有成员
答案 0 :(得分:10)
如果你想要一个演员表,那就投吧:
struct A
{
int a;
int b;
int c;
operator int()
{
return a + b + c;
}
};
A a = { 10, 20, 30 };
printf("%d\n", (int)a);
输出将是
60
答案 1 :(得分:5)
这是未定义的行为,因此在某种意义上,对于此函数调用,每个可能的行为都可以称为“正常”。但可以解释一下。
printf
在格式字符串后面接受可变数量的参数。如何打包这些是留给实现的。似乎Visual C ++在内存中打包参数的方式与打包struct A
成员的方式相同,因此每次在内部调用va_arg
时,它都会获得a
中的下一个元素。 / p>
关于转换,您不能依赖于varargs上下文中的自动转储,因为可选参数没有类型。 printf
被声明为int printf(char const *, ...)
。 ...
是一系列无类型参数。
答案 2 :(得分:5)
没有像C / C ++这样的东西,你的代码只是两者的混合。特别是它不能使用标准C编译器进行编译,因为您在struct
的声明中缺少a
关键字。
供您使用printf
。首先,如果这是C ++,你不应该这样做。它有自己的IO机制。使用它们。
然后将结构作为参数放在...
列表中是未定义的行为。你运气不好,编译器做了它做的事情。它可能只是悲伤的“不,不,不这样做”,或者至少给了你一个警告。
答案 3 :(得分:4)
您在堆栈上放置了三个整数,然后检索了三个整数(每个“%d”一个)。是的,这是正常的 - 但在“真的丑陋黑客”的领域(和未定义的行为启动,正如基座正确评论)。
答案 4 :(得分:3)
这是偶然的。大多数情况下,当您的printf
arg计数或类型不匹配时,结果将不会很好。
如果您希望C ++使用ostream/cout
std::cout << a.a << ' ' << a.b << ' ' << a.c << std::endl;
如果您想使用非脆弱的C代码:
printf("%d %d %d\n", a.a, a.b, a.c);
答案 5 :(得分:2)
这是因为结构的内存布局。整体是紧随其后的。因此,将结构放在printf调用中基本上就像将每个结构放在一个接一个上一样
答案 6 :(得分:2)
printf的行为方式有很多与编译器/环境相关的东西。
printf表面上使用了C的var args功能,当你有声明时
int printf(char* formatStr, ...)
你可以在“...”中传递多个参数。然后在printf的主体中你会做类似下面的事情
// count how many formatters are in the format string
// and calculate "amount"
// here amount = 3
va_list valsToPrint;
va_start(valsToPrint,amount);
for (int i = 0; i < amount; ++i)
{
// treat each value as a 32-bit int and print it
}
va_end(vl);
重要的是 - 这里有很多与编译器/环境相关的东西。例如,结构可能已打包,以便每个值显示在32位边界上,以及如何从编译器实际确定va_list。我想编译器到编译器的代码可能会有一些非常不同的行为,但展示你描述的行为并不奇怪。
答案 7 :(得分:1)
printf()具有“(char *,...)”签名。这意味着“printf”函数可以处理“char *”之后的所有参数。
将结构A传递给printf()。在内存中它有以下布局:“int,int,int”。 printf()函数读取格式字符串(“%d%d%d”)并“认为”您将3个整数传递给它。而这个“假设”与结构的布局相吻合。因此它将所有字段打印为单独的值。
尝试删除“b”字段,您将看到printf()将打印“a”字段,“c”字段和 SEGMENTATION FAULT 的值。< / p>