Ошибка 2 ошибки C4430: отсутствует спецификатор типа - int. Примечание: C++ не поддерживает default-int

Я получаю эти ошибки

Ошибка 2 ошибки C4430: отсутствует спецификатор типа - int. Примечание. C++ не поддерживает ошибку ошибки 2 по умолчанию-int C4430: специфицирован отсутствующий спецификатор типа - int. Примечание: C++ не поддерживает default-int

мой код

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

#ifndef ********
#define unsigned int ********;
#endif

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

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

что делать по этому поводу.

Спасибо, Равиндра Гупта

3 ответа

Это довольно интересная ошибка; сообщение об ошибке не делает много, чтобы рассказать вам, в чем проблема.

Определение макроса:

#ifndef ********
#define unsigned int ********;
#endif

имеет несколько уровней неправильности. В определении макроса сначала определяется макрос, за которым следует последовательность, к которой он расширяется, - который обычно не должен заканчиваться точкой с запятой:

#define ******** unsigned int

Но использование макроса для этой цели - плохая идея; typedef намного лучше:

typedef unsigned int ********;

(обратите внимание, что идентификатор определяется последним, и требуется точка с запятой, макроопределения и typedef имеют очень различный синтаксис). И в отличие от макросов, нет способа проверить, был ли уже определен typedef.

******** уже должен быть определен в или но стандартный заголовок, который был добавлен к стандарту ISO ISO 1999, и принят в C++ только по стандарту ISO ISO C++, поэтому есть приличный шанс, что он не будет доступен, в зависимости от того, какую реализацию C++ вы используете. Если заголовок существует, вы можете использовать #ifdef UINT_MAX чтобы определить, определен ли ********, но это полезно только в том случае, если вы обеспокоены системами, которые вообще не имеют 32-разрядного типа без знака.

Но ваш код даже не ссылается на ******** - так почему определение макроса вызывает проблему?

Поскольку вы неправильно определили порядок, ваше определение макроса не определяет ********, оно определяет unsigned, так что любое вхождение этого слова будет расширяться до int ********; (включая точку с запятой).

Но вы также не ссылаетесь на unsigned - по крайней мере, не напрямую. Таким образом, проблема заключается в вашем определении _tmain:

int _tmain(int argc, _TCHAR* argv[])

Оба _tmain в качестве точки входа в программу и имя типа _TCHAR зависят от Microsoft. У меня нет доступа к компилятору Microsoft на данный момент, но, судя по сообщению об ошибке, которое вы видите, _TCHAR (который логически должен быть typedef), вероятно, является макросом, который расширяется до чего-то вроде unsigned short (используя 16- бит, потому что Windows любит использовать 16-разрядные символы ширины для UTF-16).

Итак, ваше определение:

int _tmain(int argc, _TCHAR* argv[])

расширяется до:

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

который, поскольку вы непреднамеренно переопределили unsigned, затем расширяется до:

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

И так как объявления параметров разделяются запятыми, а не точками с запятой, это синтаксическая ошибка. Я не уверен, почему это приводит к конкретному сообщению об ошибке, которое вы видите, но это не удивительно. Синтаксические ошибки, особенно те, которые связаны с неверно определенными макросами, часто приводят к запутыванию сообщений об ошибках.

Лучшей стратегией для чего-то подобного является, как правило, просмотр самой ранней строки, на которой компилятор сообщает об ошибке. Если само сообщение об ошибке не освещается, игнорируйте его и изучайте источник, пытаясь понять, что вы, возможно, ошиблись.

Если это не сработает (как в этом случае), попробуйте запустить свою программу через препроцессор. Большинство компиляторов на основе Unix, включая gcc, используют для этого параметр -E; Я не знаю соответствующий вариант для Microsoft. Вывод препроцессора, вероятно, будет очень многословным (он будет включать в себя искаженные копии всех заголовков, которые вы включаете, прямо или косвенно), но изучение этого может привести к чему-то полезному.

В этом конкретном случае комментирование вашей директивы #define заставит проблему уйти, что будет подсказкой, что что-то не так с #define, хотя связь между ним и сообщением об ошибке далека от очевидности.

ОБНОВИТЬ :

Моя догадка была в значительной степени неправильной. _TCHAR не является макросом; по-видимому, это typedef. Ошибка была не в определении _tmain, это было в объявлении участника:

******** emp_id;

И это провалилось просто потому, что ******** не был определен.

Сообщение об ошибке все еще вводит в заблуждение. Поскольку ******** не был объявлен, он рассматривается как обычный идентификатор, а не как имя типа. Именования типов рассматриваются как синтаксически отличные от обычных идентификаторов. Компилятор попытался оправиться от ошибки, предположив, что ******** может быть именем участника, что означает, что за ним следует точка с запятой, - но тогда объявление

********;

объявит член без явного типа. В старых версиях C это было бы законным и сделало бы члена int. Компилятор догадывается о том, что на самом деле означает код.

Кстати, если вы покажете сообщение об ошибке, сообщите нам, к какой строке он относится.


#define unsigned int ********;

Это приводит к тому, что unsigned будет макросом для int ********; , который не может быть тем, что вы хотите.


Во-первых, ******** обычно является typedef, а не макросом. Таким образом, даже если у вас есть определение в области видимости, ваш #ifdef будет делать не то.

Во-вторых, если вы хотите создать макрос с именем ******** (который я не советую), правильный порядок:

#define ******** unsigned int

Тем не менее, вам гораздо лучше, включая если у вас есть это, или чтобы получить правильное определение ********. (Я считаю, что - это С++ 11.)

licensed under cc by-sa 3.0 with attribution.