C - передача «составного / унаследованного» экземпляра структуры указателю его базового типа - PullRequest
0 голосов
/ 13 ноября 2018

Итак, у меня есть 2 структуры.

Первый:

typedef struct AST_NODE_STRUCT {
    token* tok;
} ast_node;

Другой:

typedef struct AST_BINOP_STRUCT {
    ast_node base;

    token* tok;

    ast_node* left;
    ast_node* right;
} ast_node_binop;

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

void do_something(ast_node* node) {
    ...
}

И я хочу передать экземпляр ast_node_binop структуры ... Никаких ошибок компиляции не будет, если я приведу ast_node_binop к ast_node, но Вальгринд говорит:

==6554== Memcheck, a memory error detector
==6554== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6554== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==6554== Command: ./cola.out examples/hello_world.cola
==6554== 
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554== 
==6554== Process terminating with default action of signal 11 (SIGSEGV)
==6554==  Access not within mapped region at address 0xFFE801FE8
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554==    at 0x109B20: parse_expr (parse.c:88)
==6554==  If you believe this happened as a result of a stack
==6554==  overflow in your program's main thread (unlikely but
==6554==  possible), you can try to increase the size of the
==6554==  main thread stack using the --main-stacksize= flag.
==6554==  The main thread stack size used in this run was 8388608.
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554== 
==6554== Process terminating with default action of signal 11 (SIGSEGV)
==6554==  Access not within mapped region at address 0xFFE801FD8
==6554== Stack overflow in thread #1: can't grow stack to 0xffe801000
==6554==    at 0x4A266B0: _vgnU_freeres (vg_preloaded.c:59)
==6554==  If you believe this happened as a result of a stack
==6554==  overflow in your program's main thread (unlikely but
==6554==  possible), you can try to increase the size of the
==6554==  main thread stack using the --main-stacksize= flag.
==6554==  The main thread stack size used in this run was 8388608.
==6554== 
==6554== HEAP SUMMARY:
==6554==     in use at exit: 4,587 bytes in 6 blocks
==6554==   total heap usage: 16 allocs, 10 frees, 9,281 bytes allocated
==6554== 
==6554== LEAK SUMMARY:
==6554==    definitely lost: 0 bytes in 0 blocks
==6554==    indirectly lost: 0 bytes in 0 blocks
==6554==      possibly lost: 0 bytes in 0 blocks
==6554==    still reachable: 4,587 bytes in 6 blocks
==6554==         suppressed: 0 bytes in 0 blocks

IПосмотрев на этот стековый поток сообщений: Наследование структур в C , чтобы узнать, как реализовать наследование "struct" в C.

Я просто хочу иметь возможность передавать экземпляры структуры, производные отдругая структура в функции, которая ожидает базовую / родительскую структуру.

Как правильно это сделать?У меня будет несколько «производных» структур из ast_node, и я не всегда буду знать , какая это производная структура, я просто знаю, что они всегда будут производными от ast_node Начиная с: ast_node base;в структуре.

Я знаю, что это сбивает с толку, но, надеюсь, вы поймете, чего я пытаюсь достичь.

Вот parse.c, так как люди в комментариях сказали, что Вэлгринд жаловался на что-то еще: https://pastebin.com/SvqeHKqs

1 Ответ

0 голосов
/ 13 ноября 2018

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

Совершенно хорошо и четко определено преобразовать ast_node_binop* в ast_node*, а затем получить доступ к данным внутри ast_node_binop этой функции.

Формально это гарантируется C17 6.5 §7, ast_node_binop - это агрегат, который включает в себя тип lvalue ast_node среди своих членов. Это первый член структуры, поэтому вопросы, касающиеся заполнения и выравнивания, также не применяются.

...