错误2错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持default-int

时间:2013-12-14 06:25:18

标签: c++

我收到这些错误

  

错误2错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持default-int   错误2错误C4430:缺少类型说明符 - 假定为int。注意:C ++不支持default-int

我的代码是

#include "stdafx.h"
#include "iostream"

#ifndef uint32_t
#define unsigned int    uint32_t;
#endif

struct employee
{
    char        emp_name[20];
    uint32_t    emp_id;
};

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

该怎么做。

谢谢, 拉文德拉古普塔

3 个答案:

答案 0 :(得分:4)

这实际上是一个相当有趣的错误;错误信息并没有告诉你问题是什么。

我最初的猜测很大程度上是错误的,但我现在已经把它留在了原地。见下文。

此代码:

#ifndef uint32_t
#define unsigned int    uint32_t;
#endif

不正确。正在定义的宏的名称紧跟在#define之后,宏定义通常不应包含分号。 (宏定义语法与声明语法完全不同。)而不是定义uint32_t,而是定义unsigned,并且尝试重新定义语言关键字会导致严重问题。另外,#ifndef没有用,因为uint32_t(如果它是通过"stdafx.h"定义的)是typedef,而不是宏。您可以使用#ifdef UINT32_MAX检查是否已定义`uint32_t。正确的版本是:

#ifndef UINT32_MAX
#define uint32_t unsigned int
#endif

或者,甚至更好:

#ifndef UINT32_MAX
typedef unsigned int uint32_t;
#endif

这需要修复,但它并没有引起你所看到的问题。显然uint32_t未在您的实现中定义,导致此声明:

uint32_t    emp_id;

失败。

错误消息仍然具有误导性。由于尚未声明uint32_t,因此将其视为普通标识符,而不是类型名称 - 并且类型名称被视为语法与普通标识符不同。编译器试图通过猜测uint32_t可能是成员名称来尝试从错误中恢复,这意味着它应该后跟分号 - 但随后是声明

uint32_t;

会声明没有明确类型的成员。在C的旧版本中,这将是合法的,并且会使成员成为int。编译器猜测代码的实际含义是错误的。

顺便提一下,如果您显示错误消息,告诉我们它适用于哪一行。


我最初关于问题原因的猜测,结果证明是不正确的。我猜到_TCHAR是一个宏,但它实际上是typedef


宏定义:

#ifndef uint32_t
#define unsigned int    uint32_t;
#endif

有几个层次的错误。在宏定义中,首先定义的宏,然后是它扩展到的序列 - 通常以分号结束:

#define uint32_t unsigned int

但是为此目的使用宏是一个坏主意; typedef要好得多:

typedef unsigned int uint32_t;

(请注意,定义的标识符是最后一个,需要分号;宏定义和typedef具有非常不同的语法)。与宏不同的是,无法测试typedef是否已被定义。

uint32_t应该已经在<stdint.h><cstdint>中定义了 - 但这是一个标准的标题,它是由1999 ISO C标准添加到C中的,并在C ++仅适用于2011 ISO C ++标准,因此根据您正在使用的C ++实现,它不太可能无法使用。如果标题存在,您可以使用#ifdef UINT_MAX来确定是否已定义uint32_t,但只有在您担心不具备32的系统时才有用{}} -bit无符号类型。

但您的代码甚至没有引用uint32_t - 那么为什么宏定义会导致问题?

由于订单错误,您的宏定义并未定义uint32_t,因此定义unsigned,以便该字词的任何出现都会扩展为int uint32_t;(包括分号)。

但是你也没有引用unsigned - 至少不是直接引用_tmain。那么,问题在于您对int _tmain(int argc, _TCHAR* argv[])

的定义
_tmain

作为程序入口点的_TCHAR和类型名称_TCHAR都是Microsoft特定的。我目前无法访问Microsoft编译器,但根据您看到的错误消息判断,unsigned short(逻辑 应该是typedef)是可能是一个扩展为类似int _tmain(int argc, _TCHAR* argv[]) 的宏(使用16位类型,因为Windows喜欢使用16位宽字符作为UTF-16)。

所以你的定义:

int _tmain(int argc, unsigned short* argv[])

扩展为:

unsigned

,因为您无意中重新定义了int _tmain(int argc, int uint32_t; short* argv[]) ,然后扩展为:

-E

由于参数声明以逗号分隔,而不是以分号分隔,因此这是语法错误。我不确定为什么会导致您看到的特定错误消息,但这并非令人惊讶。语法错误,特别是那些涉及错误定义的宏的错误,通常会导致混淆错误消息。

这样的最佳策略是通常来查看编译器报告错误的最早行。如果错误消息本身没有启发,请忽略它并研究来源,试图找出你可能出错的地方。

如果失败(就像在这种情况下那样),请尝试仅通过预处理器运行程序。大多数基于Unix的编译器,包括gcc,都使用#define选项;我不知道微软的相应选项。预处理器的输出可能非常冗长(它将包括您直接或间接包含的所有标头的损坏副本),但检查它可能会引导您做一些有用的事情。

在这种特殊情况下,注释掉你的#define指令会使错误消失(更正:不,它不会),这将是一个线索, {{1}}出现了问题,即使它与错误信息之间的关系并不明显。

答案 1 :(得分:2)

#define unsigned int    uint32_t;

这会导致unsigned成为int uint32_t;的宏,这可能不是您想要的。

答案 2 :(得分:1)

首先,uint32_t通常是typedef,而不是宏。因此,即使您在范围内有定义,您的#ifdef也会做错事。

其次,如果 想要制作一个名为uint32_t的宏(我不建议),那么正确的顺序是:

#define uint32_t unsigned int

然而,如果您拥有<cstdint>,或者<stdint.h>获得uint32_t的正确定义,您 会更好 1}}。 (我相信<cstdint>是C ++ 11。)