在微软vc2010编译器中发现了一个错误 [英] discovered a bug in microsoft vc2010 compiler

查看:93
本文介绍了在微软vc2010编译器中发现了一个错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



Microsoft VS 2010 cpp编译器中存在以下错误。

  void  func1( int  a, int  b , int  c ...)
{
va_list ap;
va_start(ap,b);
// 这里的一些代码
va_end(ap);
}





微软已经改进了优化,现在参数为b(确切地说,之前的第二个参数是... ecx寄存器。几乎在所有情况下都没有问题,但在上面的例子中,指令va_start(ap,b)不能接受ecx的地址,并生成错误的代码。预计编译器应该生成错误一旦它无法获取寄存器参数的地址。

我把这篇文章放在这里是因为我无法连接到微软,因为我所居住的国家受到制裁,原谅正在进行中

mr.abzadeh



编辑:此代码正常工作直到弱势,然后我注意到错误的编译并更改我的代码。我没有更改我的项目设置。我使用visual studio 2010 ultimate SP1,问题发生在releasemode,优化上。

解决方案

让我感到惊讶的是你的代码,是你没有使用para米 c ,但 b 开始扫描可选参数。关于va_start的文档声明:

  void  va_start(
va_list arg_ptr,
prev_param
); // (ANSI版本)



va_start将arg_ptr设置为传递给函数的参数列表中的第一个可选参数。参数arg_ptr必须具有va_list类型。参数prev_param是参数列表中第一个可选参数前面的必需参数的名称。如果使用寄存器存储类声明prev_param,则宏的行为是未定义的。 va_start必须在第一次使用va_arg之前使用。



所以,你认为你在这里建立一个没有记录的功能。


正如nv3指出的那样,你没有正确使用宏。如果你以任何方式使用它,除了文档中描述的那样,那么所有的赌注都是关闭的,如果它没有按你认为的那样做,你就不能抱怨。如果您认为这是不正确的,那么您应该与Microsoft讨论此事而不是在此处发帖。


以下代码

  #include   <   stdio.h  >  
#include < span class =code-preprocessor> < stdarg.h >
void func1( int a, int b, int c,...)
{
int n,k;
va_list ap;
va_start(ap,b);
// 这里的一些代码
printf( a =%d,b =%d,c =%d,其他:\ n,a,b,c) ;
for (n = 0 ; n< c; n ++)
{
k = va_arg(ap, int );
printf( %d \ n,k);
}
va_end(ap);
}
int main()
{
int a = 5 ;
func1(a, 5 3 2 3 4 );
}





在我的 Visual C ++ 2010 Express Edition上产生预期输出


Hello guys,

The following bug exists in the Microsoft VS 2010 cpp compiler.

void func1( int a, int b, int c... )
{
  va_list ap;
  va_start( ap, b );
  //some code here
  va_end(ap);
}



Microsoft has improved optimizations and now parameter b(exactly speaking, the 2nd parameter before ... is passed in ecx register. there is no problem with this in almost all cases, but in the example above, the instruction va_start( ap, b ) can not take address of ecx, and generates wrong code. It is expected that the compiler should generate an error once it can not take the address of a register parameter.
I put this post here because I could not connect to microsoft, due to sanctions on the country I live in, pardon in progress
mr.abzadeh

Edit: This code worked correctly until a weak ago, and then I noticed the wrong compilation and changed my code. I have not changed my project settings. I use visual studio 2010 ultimate SP1, and the problem occurs in releasemode, optimizations on.

解决方案

What surprises me in your code, is that you are not using parameter c, but b to start the scan of optional parameters. The documentation on va_start states:

void va_start(
   va_list arg_ptr,
      prev_param 
); // (ANSI version)


va_start sets arg_ptr to the first optional argument in the list of arguments passed to the function. The argument arg_ptr must have va_list type. The argument prev_param is the name of the required parameter immediately preceding the first optional argument in the argument list. If prev_param is declared with the register storage class, the macro''s behavior is undefined. va_start must be used before va_arg is used for the first time.

So, in opinion you are building here on a non-documented feature.


As nv3 points out, you are not using the macro correctly. If you use it any any way other than as described in the documentation, then all bets are off, and you cannot complain if it does not do what you think it should. If you believe that is incorrect then you should be talking to Microsoft about it rather than posting here.


The following code

#include<stdio.h>
#include <stdarg.h>
void func1( int a, int b, int c,... )
{
	int n, k;
  va_list ap;
  va_start( ap, b );
  //some code here
	printf(" a=%d, b=%d, c=%d, other:\n", a,b,c);
	for (n=0; n<c; n++)
	{
		k = va_arg(ap, int);
		printf("%d\n", k);
	}
  va_end(ap);
}
int main()
{
	int a=5;
	func1(a,5,3,2,3,4); 
}



produces the expected output on my Visual C++ 2010 Express Edition.


这篇关于在微软vc2010编译器中发现了一个错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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