c - GCC 在 C 中使用可变参数时报告大量警告

标签 c variadic-functions

这是我的代码片段:[Full Code]

void Draw_Square (HDC DeviceContext, int Cnt, ...)
{
    int Cnt_1, Cnt_2, Cnt_3, Cnt_4;
    for (Cnt_1 = 0; Cnt_1 < 4; Cnt_1++)
    {
        for (Cnt_2 = 0; Cnt_2 < 6; Cnt_2++)
        {
            va_list Ap;
            va_start (Ap, (Cnt*4));
            for (Cnt_3 = 0; Cnt_3 < Cnt; Cnt++)
                Draw_Line (DeviceContext, (Cnt_1*6+Cnt_2), va_arg (Ap, short), va_arg (Ap, short), va_arg (Ap, int), va_arg (Ap, COLORREF));
            va_end (Ap);
        }
        Sleep (User_Def_Delay);
    }
}

GCC/mingw32 报告:

|   |In function 'Draw_Square':                                                              |
|393|warning: second parameter of 'va_start' not last named argument [enabled by default]    |
|395|warning: 'short int' is promoted to 'int' when passed through '...' [enabled by default]|
|395|note: (so you should pass 'int' not 'short int' to 'va_arg')                            |
|395|note: if this code is reached, the program will abort                                   |
|395|warning: 'short int' is promoted to 'int' when passed through '...' [enabled by default]|
|395|note: if this code is reached, the program will abort                                   |

为什么?类型错误?

谢谢。

添加:

我已经修改了我的代码,但仍然失败。

void Draw_Square (HDC DeviceContext, int Cnt, ...)
{
 va_list Ap;
 va_start (Ap, Cnt);
 int Cnt_1, Cnt_2, Cnt_3;
 for (Cnt_1 = 0; Cnt_1 < 4; Cnt_1++)
 {
  for (Cnt_2 = 0; Cnt_2 < 6; Cnt_2++)
  {
   for (Cnt_3 = 0; Cnt_3 < Cnt; Cnt++)
    Draw_Line (DeviceContext, (Cnt_1*6+Cnt_2), (short)va_arg (Ap, int), (short)va_arg (Ap, int), va_arg (Ap, int), va_arg (Ap, COLORREF));
  }
  Sleep (User_Def_Delay);
 }
 va_end (Ap);
}

没有警告

最佳答案

Read the manual .你想要这样的东西:

void Draw_Square (HDC DeviceContext, int Cnt, ...)
{
    va_list Ap;
    va_start(Ap, Cnt);

    // ... loop can use "va_arg" repeatedly

    va_end(Ap);
}

通常,将强制参数(如 Cnt_1、...、Cnt_4)作为可变参数传递是没有意义的。然后进行正常的论证。在某些情况下,有时可变参数对固定参数有意义(例如,当您实现 Linux 系统调用接口(interface)时),但这种情况很少见,容易出错,而且比好的设计更像是最后的手段。但如果你必须这样做,你总是可以这样做:

    // prologue as above

    short Cnt_1 = va_args(Ap, int);
    short Cnt_2 = va_args(Ap, int);
    short Cnt_3 = va_args(Ap, int);
    short Cnt_4 = va_args(Ap, int);

    // loop

    // epilogue

此外,您不能将任何短于 int 的整数作为变量参数传递,因为它们总是会被标准提升为 intunsigned int。所以 va_args(Ap, short) 永远不会正确,它应该是 va_args(Ap, int):short 的转换intshort 定义明确并保留原始值。

强调最后一点:如果您要传递一个unsigned short,您需要将 va-cast 转换为 unsigned int:

unsigned short n = va_args(Ap, unsigned int);

无论在您的平台上 unsigned short 是否默认提升为 int unsigned int(两者都是可能的;这取决于平台):正如链接文档所说,只要两个版本都是彼此的符号变体并且所讨论的是由两种类型表示。情况确实如此:如果 unsigned short 被提升为 int,那么它的值也必须自动由 unsigned int 表示,因为无符号类型可以表示其有符号对应物的所有非负值。

关于c - GCC 在 C 中使用可变参数时报告大量警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20441700/

相关文章:

c字符串标记化问题

haskell - 如何在 Haskell 中连接变量参数?

c - 我有一个点在图像周围弹跳。需要计算像素组(物体表面)的反射角

c - 如何根据类型重命名变量

c - WPF 中的 SelectedRow 和 DataBoundItem 是如何获取的?

java - 使用可变参数重载方法

c++ - 来自省(introspection)略号的 va_list 如何与 vfprintf() 调用交互?

c - select() 超时后不返回

java - 使用可变参数的方法重载

flash - 如何将可变参数作为扩展列表传递给方法?