Есть ли большая разница, если я использую что-то вроде этого:
void print_struct( void *ptr_to_struct )
вместо:
void print_struct( struct data *ptr_to_struct )
Я спрашиваю об этом, потому что я просто застрял в чем-то, чего не могу понять, и почему это не работает следующим образом:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print_struct( struct data *ptr_to_struct );
struct data{
char name[ 256 ];
};
int main( void )
{
struct data ptr;
strcpy ( ptr.name, "George" );
print_struct_1( &ptr);
}
void print_struct( struct data *ptr_to_struct )
{
struct data *ptr = ptr_to_struct;
printf("Name = %s\n", ptr->name );
}
Я получил:
error: ‘struct data’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
Но если я перееду:
void print_struct( struct data *ptr_to_struct );
После:
struct data{
char name[ 256 ];
};
Компилируется нормально.
Я не понимаю следующего:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print_struct( void *ptr_to_struct );
struct data{
char name[ 256 ];
};
//void print_struct( void *ptr_to_struct );
int main( void )
{
struct data ptr;
strcpy ( ptr.name, "George" );
print_struct_1( &ptr);
}
void print_struct( void *ptr_to_struct )
{
struct data *ptr = ( struct data * )ptr_to_struct;
printf("Name = %s\n", ptr->name );
}
Нет, если я использую:
void print_struct( void *ptr_to_struct );
До или после:
struct data{
char name[ 256 ];
};
Программа работает нормально.
Почему такая разница?





Когда вы ссылаетесь на неизвестный тип struct something в прототипе функции, он фактически объявляет новый тип структуры. Однако новый тип будет локальным для этого прототипа. Новый тип не будет связан с каким-либо типом struct something с одинаковыми именами, объявленным впоследствии. Например
void foo(struct S *p) {}
struct S { int i; };
int main(void) {
struct S s;
foo(&s); // ERROR: the pointer types are unrelated
}
В принципе, не делайте этого. Не используйте неизвестные типы struct something в прототипах функций. Бессмысленно. Практически всегда это указание на опечатку или другую ошибку. Вот почему компилятор выдает предупреждение.
Такие типы структур должны быть объявлены прототипом до. Вы можете переставить свои объявления (как вы уже пробовали). Или вы можете предварительно объявить тип структуры
struct data;
void print_struct( struct data *ptr_to_struct );
struct data{
char name[ 256 ];
};
Это тоже будет работать правильно.
Объявление прототипа функции с параметром типа void * и последующее определение той же функции с параметром типа struct something * приводит к неопределенному поведению, даже если ваша программа, похоже, "работает нормально".
@Michael B .: То, что у вас есть по этой ссылке, выглядит нормально. Однако некоторые квалификаторы const совершенно необоснованны.
Some const qualifiers are completely unjustified Почему? Я имею в виду, что цель состоит в том, чтобы сообщить компилятору, что я не касаюсь этого указателя или его указанного значения. Или я ошибаюсь?
@Michael B: Ну, в таком случае сделайте это последовательным: внутри вашего print_struct объявите ptr как const struct data *ptr. Это также сделает ненужным гипс. В настоящее время вы используете это приведение, чтобы отбросить некоторые из ваших const. Какой смысл использовать const, если вы все равно собираетесь сразу выбросить?
Теперь я понимаю. Спасибо.
Так что, если я использую его Как это нормально, или может привести к
UB?