Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > вопрос по typedef struct


Автор: leniviy 16.3.2009, 15:07
Привет. Есть не моя структура и существующий код, в котором объявляются указатели на неё с ключевым словом struct.
Можно ли задекларировать новый тип - синоним существующего, чтобы работал в .c и .cpp и переменные этого типа можно было объявлять с модификатором struct?

Код

typedef struct AAA
{
    int i;
} AAA;

AAA* p1; //OK
struct AAA* p2; //OK

//struct BBB; //.c: OK; .cpp: causes on next line: 'BBB' : redefinition; different basic types
typedef struct AAA BBB;

BBB* p3; //OK
struct BBB* p4; //.c: OK; .cpp: error C2371: 'BBB' : redefinition; different basic types


Похоже, что при объявлении нового типа он не помечается как "структура"

Автор: math64 16.3.2009, 15:17
В объявлении typedef struct AAA BBB; BBB объявляется как тип, а не структура. В C имена структур и типов находятся в разных пространствах имён, ключевое слово struct обязательно, в C++ struct можно опускать, но использование struct перед именем типа запрещено в обоих языках.
Можно написать
Код
#define BBB AAA
, но в этом случае ВВВ будет заменяться на AAA всегда

Автор: leniviy 16.3.2009, 15:42
да. Я уже в своё время намучился с макросом EOF. 

Автор: Dem_max 16.3.2009, 16:30
Код

typedef struct THEAD
{
  char  Version;
  DWORD RecordsCount;
  WORD  HeaderSize;
  WORD  RecordSize;
} THEAD;

THEAD BBB;
typedef THEAD *PBBB;

//---------------------------------------------------------------------------
void func()
{
BBB.Version = 1;

PBBB->Version = 1;
}

Автор: mes 16.3.2009, 16:37
Dem_max, какое отношение имеет приведенный код к сабжу ?

Автор: Dem_max 16.3.2009, 16:40
mes
чел хотел переопределение названия структуры

Автор: mes 16.3.2009, 19:14
Цитата(Dem_max @  16.3.2009,  15:40 Найти цитируемый пост)
чел хотел переопределение названия структуры 

не совсем так, eму требуется следующее  :
Цитата(leniviy @  16.3.2009,  14:07 Найти цитируемый пост)
Есть не моя структура и существующий код, в котором объявляются указатели на неё с ключевым словом struct.
Можно ли задекларировать новый тип - синоним существующего, чтобы работал в .c и .cpp и переменные этого типа можно было объявлять с модификатором struct?

smile

Автор: Dem_max 16.3.2009, 19:23
mes
тогда
struct THEAD stgr; или THEAD stgr;

Автор: mes 16.3.2009, 20:53
Цитата(Dem_max @  16.3.2009,  18:23 Найти цитируемый пост)
тогда
struct THEAD stgr; или THEAD stgr; 


если структура заранее объявлена, как struct Т;  то не получится Т тайпдефить к другой структуре. 
т.е  не допустима такая последовательность :
Код

struct T;
typedef Some T;

именно обход этой проблемы и ищет тс, а причину описал math64:
Цитата(math64 @  16.3.2009,  14:17 Найти цитируемый пост)
В объявлении typedef struct AAA BBB; BBB объявляется как тип, а не структура. В C имена структур и типов находятся в разных пространствах имён, ключевое слово struct обязательно, в C++ struct можно опускать, но использование struct перед именем типа запрещено в обоих языках.


smile

Автор: Dem_max 16.3.2009, 21:06
mes
Я взял книжку 1990 года про СИ и привел пример, там от С++ и речи не вели.

Автор: ParaPik 8.4.2009, 20:54
Вообще, ключевое слово struct также используется для того, чтобы избежать неоднозначности. Т.е. существует два случая испоьзования struct:
1. Объявление структуры.
2. Решение неоднозначности.
Например:
Код

struct my_struct
{
     int i_num;
     double d_num;
};

void func()
{
    char my_struct[] = "String";
    struct my_struct obj = {5, 10.5};
}

Автор: zim22 8.4.2009, 21:03
Цитата(ParaPik @  8.4.2009,  20:54 Найти цитируемый пост)
2. Решение неоднозначности.

какая такая неоднозначность?
если слово struct убрать - оно вообще не скомпилится smile

Код

void func()
{
    char my_struct[] = "String";
    my_struct obj = {5, 10.5};
}

Автор: J0ker 8.4.2009, 22:50
в C++ типы "T" и "struct T" эквивалентны - в отличии от plain C

Автор: mes 8.4.2009, 22:55
Цитата(zim22 @  8.4.2009,  20:03 Найти цитируемый пост)
какая такая неоднозначность?
если слово struct убрать - оно вообще не скомпилится smile

как раз о том и речь, без указания struct в приведенном примере возникает неоднозначность и как следствие невозможность компиляции. smile

Автор: ParaPik 9.4.2009, 16:33
Дело в том, что C++, в отличии от других языков программирования, таких как C# и Java, позволяет объявлять переменную с тем же именем, что и название, в данном случае, структуры, но с другим типом(char, int, double и так далее). И чтобы указать компилятору, что вы имеете в виду  именно тип структуру, то надо перед именем структуры поставить ключевое слово struct(это же относится и к ключевому слову class). А то, с чего началась данная тема, вообще зависит от реализации компилятора. Так что, некоторые старые компиляторы, а вполне возможно и новые, нормально воспримут код, написанный в начале темы.  

Автор: Любитель 9.4.2009, 16:40
К типу, объявленному через typedef невозможно обратиться через ключевое слово struct. Ни в С, ни в С++. Что впрочем уже было сказано давно в этой теме. Так что следующее утверждение ложно:

Цитата(ParaPik @  9.4.2009,  16:33 Найти цитируемый пост)
Так что, некоторые старые компиляторы, а вполне возможно и новые, нормально воспримут код, написанный в начале темы.  


Автор: zim22 9.4.2009, 16:41
Цитата(ParaPik @  9.4.2009,  16:33 Найти цитируемый пост)
C++ ... позволяет объявлять переменную с тем же именем, что и название...но с другим типом(char, int, double и так далее)

покажите пожалуйста на примере. первый раз слышу о такой возможности с++
я пытался и так:
Код

extern char var1;
extern int var1;


и так:
Код

double *dp;
char *dp;

но компилятор ругается 
error C2371: 'dp' : redefinition; different basic types

Автор: leniviy 9.4.2009, 17:06
Цитата(ParaPik @  9.4.2009,  16:33 Найти цитируемый пост)
позволяет объявлять переменную с тем же именем, что и название, в данном случае, структуры

Сомнительная польза. По-моему, единственное полезное применение struct - объявить указатель на ещё не объявленную структуру.
Например, так:
Код

typedef struct AAA {
    struct BBB* pBBB;
    int i;
} AAA;

typedef struct BBB {
    struct AAA* pAAA;
    int i;
} BBB;


Автор: math64 10.4.2009, 07:29
leniviy, твой код будет компилироваться только в C. объявив struct BBB внутри struct AAA, ты объявляешь struct AAA::ВВB.
Правильно будет:
Код

struct AAA;
struct BBB;
typedef struct AAA {
    struct BBB* pBBB;
    int i;
} AAA;

typedef struct BBB {
    struct AAA* pAAA;
    int i;
} BBB;


Автор: mes 10.4.2009, 13:20


Цитата(zim22 @  9.4.2009,  15:41 Найти цитируемый пост)
Цитата

C++ ... позволяет объявлять переменную с тем же именем, что и название...но с другим типом(char, int, double и так далее)

покажите пожалуйста на примере. первый раз слышу о такой возможности с++

имхо, имелось ввиду это:
Цитата(ParaPik @  8.4.2009,  19:54 Найти цитируемый пост)
Код

struct my_struct
{
     int i_num;
     double d_num;
};
void func()
{
    char my_struct[] = "String";
    struct my_struct obj = {5, 10.5};
}


Автор: UnrealMan 10.4.2009, 17:22
Цитата(mes @  10.4.2009,  13:20 Найти цитируемый пост)
имхо, имелось ввиду это

Скорее, что-то вроде этого:

Код
int x;
struct x {};

int main()
{
    x = 5;
    {
        struct x *x;
        x = (struct x *)0;
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)