2013-05-23 2 views
3

Я реализовал связанный список в C (не C++), который хранит указатели на данные. Я хотел бы иметь несколько деклараций для своих функций (для обеспечения безопасности типов), но каждый из них ссылается на одно и то же определение (потому что нет фактической разницы между указателями на разные типы данных, поэтому использование одного и того же кода уменьшает пространство).Связать несколько деклараций с тем же определением

Есть ли у кого-нибудь идеи о том, как достичь этого (или каких-либо лучших способов сделать это)? Портативное решение, очевидно, лучше всего, но мне действительно нужно что-то, что работает в GCC.

+0

Написал ли несколько деклараций действительно какой-либо тип безопасности? Я предполагаю, что у вас есть функции вставки/удаления, которые перегружены - что мешает вам вставлять один тип и удалять с другим? – derekerdmann

+0

@derekerdmann: В одном из объявлений принимается int * (например), поэтому компилятор будет жаловаться, если вы попытаетесь передать это объявление myStruct *. Определение будет принимать пустоту *. Компилятор увидит каждое объявление как отдельную функцию, и они становятся только теми же, когда линкер добирается до них. –

+0

Декларация также требует принятия 'void *' для 'myStruct *' для принятия - это то, на что смотрит компилятор, когда выясняется, совпадают ли аргументы, а не определение. – derekerdmann

ответ

1

Я считаю, что вы могли бы добиться этого с помощью определений типов для функциональных прототипов и литьем общего решения (которое сделок в void* s) на конкретный прототип. Это должно быть безопасно для компиляции, потому что все указатели будут одинакового размера.

Рассмотрим следующий пример:

do_something.h:

typedef void (*do_something_with_int_t)(int *i); 
extern do_something_with_int_t do_something_with_int; 

typedef void (*do_something_with_string_t)(char *s); 
extern do_something_with_string_t do_something_with_string; 

do_something.c

#include "do_something.h" 

void do_something_generic(void* p) { 
    // Do something generic with p 
} 


do_something_with_int_t do_something_with_int = 
    (do_something_with_int_t)do_something_generic; 

do_something_with_string_t do_something_with_string = 
    (do_something_with_string_t)do_something_generic; 

Как долго, как do_something_generic действительно тип данных агностик (т.е. действительно не имеет значения, что p указывает на), тогда это было бы нормально.

0
#include <stdio.h> 
struct common_type { 
    int type; 
}; 

struct type1 { 
    int type; 
    int value; 
}; 

struct type2 { 
    int type; 
    char* p; 
}; 

int func(void *para) { 
    switch (((struct common_type*)para)->type) { 
     case 1: 
      printf("type1,value:%d\n",((struct type1*)para)->value); 
      break; 
     case 2: 
      printf("type2,content:%s\n",((struct type2*)para)->p); 
      break; 
    } 
} 

int main() { 
    char *s = "word"; 
    struct type1 t1 = {1,1}; 
    struct type2 t2; 
    t2.type = 2; 
    t2.p = s; 
    func((void*)&t1); 
    func((void*)&t2); 
} 
+0

Вы даже прочитали вопрос? В вашем ответе рассматривается общая проблема множественного определения, и это не то, о чем я говорю. Мой вопрос касается практически противоположности, используя одно определение для нескольких объявлений. Я ценю, что вы приложили все усилия, чтобы помочь, но я был бы признателен за это, если вы приложите это усилие к правильному вопросу. –

+0

В этом случае поместите defintion в файл заголовка и объявления в файлах, которые используют struct. Я написал некоторый код addational, вы имели в виду это? – vvy

+0

Нет; который все еще затрагивает неправильный вопрос. Я ищу способ иметь несколько деклараций, которые связаны с одной и той же «общей» функцией. –

0

Если это C (не C++), то следующее будет работать нормально. Вы можете адаптировать концепцию к вашим потребностям.

tt.h

typedef struct { 
    int ii; 
} Type_1; 

typedef struct { 
    int ii; 
} Type_2; 

int foo_1(Type_1* ptr) __attribute__((alias("foo"))); 
int foo_2(Type_2* ptr) __attribute__((alias("foo"))); 

tt.c

#include <stdio.h> 

#include "tt.h" 

int main() { 
    Type_1 t_1; 
    Type_2 t_2; 
    foo_1(&t_1); 
    foo_2(&t_2); 
} 

int foo(void* arg) { 
    printf("foo: %p\n", arg); 
} 
+0

Это будет работать в GCC, но '__attribute__' не переносится. – Anthony

+0

@ anthony-arnold: Меня не волнует переносимость, поэтому я собираюсь использовать ответ Ziffusion в своем коде (для эффективности, я считаю, что ваш ответ принимает дополнительную инструкцию или два за вызов). Тем не менее, я принимаю ваш ответ, потому что это более общий ответ для того, кто может столкнуться с этим вопросом позже. Спасибо вам обоим! –

+0

@LonelyIsland См. [Этот вопрос] (http://stackoverflow.com/questions/2438539/does-function-pointer-make-the-program-slow) для повышения эффективности экзамена. Хороший компилятор будет генерировать практически тот же машинный код. – Anthony

Смежные вопросы