Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> возможна ли статическая проверка типов? (ANSI C), static_assert(type1 typedef of long); 
:(
    Опции темы
korian
Дата 28.9.2011, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Здравствуйте!
Меня интересует такой вопрос, возможно ли статически проверить, что тип type1 является typedef'ом типа type2 среднствами ANSI C.

Мне надо нечто типа такого:
Код

typedef long type1;

static_assert(type1 typedef of long);
#define printf_type1 "ld"

Соответсвенно, хотелось бы увидеть ошубку компиляции, если кто-то, когда-то изменит typedef типа type1.
Возможно ли это сделать средствами ANSI C? define'ами всякими и тд...

Спасибо.
PM   Вверх
boostcoder
Дата 28.9.2011, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Код

#include <stdio.h>

int main() {
   typedef char mychar;
   typedef unsigned char myuchar;
   printf("%d, %d",
      __builtin_types_compatible_p(char, mychar),
      __builtin_types_compatible_p(mychar, myuchar)
   );
}


Добавлено через 13 минут и 16 секунд
правда, это не стандартный способ. это расширения GCC.
PM WWW   Вверх
boostcoder
Дата 28.9.2011, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



ну и статик ассерт:
Код


#include <stdio.h>

#define IS_SAME_TYPES(type1, type2) \
   extern char __##type1##_##type2##__TYPES_ARE_NOT_THE_SAME__[ \
      __builtin_types_compatible_p(type1, type2)?1:-1 \
   ];

int main() {
   typedef char mychar;
   typedef unsigned char myuchar;
   IS_SAME_TYPES(char, mychar);
   IS_SAME_TYPES(mychar, myuchar); // error: size of array ‘__mychar_myuchar__TYPES_ARE_NOT_THE_SAME__’ is negative
}


PM WWW   Вверх
korian
Дата 28.9.2011, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



boostcoder, спасибо, то, что надо!

Цитата(boostcoder @  28.9.2011,  18:53 Найти цитируемый пост)
правда, это не стандартный способ. это расширения GCC.

Это, конечно, проблема. Но, если существуют такие же штуки под используемыми платформами, то она решаема.
Поэтому буду очень благодарен, если кто сообщит есть ли подобные возможности у компиляторов:
Visual Studio 2010
Solrais (стандартный комплятор операционки)
AIX (стандартный комплятор операционки)
HP-UX (стандартный комплятор операционки)

PM   Вверх
math64
Дата 29.9.2011, 16:06 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Может быть достаточна неполная проверка, но зато работающая везде?
Код

template<type type1, type type2>
class CheckTypesAreSame {
private:
  static inline void dummy(type1 var1, type2 var2) {
    char c[sizeof(type1) == sizeof(type2) ? 1 : -1];
    var1 = var2;
    var2 = var1;
  }
};

PM   Вверх
mes
Дата 29.9.2011, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



math64
Цитата(korian @  28.9.2011,  18:46 Найти цитируемый пост)
 среднствами ANSI C.

Цитата(math64 @  29.9.2011,  15:06 Найти цитируемый пост)
Код

template<type type1, type type2>




--------------------
PM MAIL WWW   Вверх
math64
Дата 29.9.2011, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Не заметил, что нужно на C. Но суть идеи можно реализовать на C - проверить размеры типов на равенство и возможность копирования из type1* в type2* (для C++ тоже надо сравнивать указатели, для классов могут быть переопределены операторы присваивания) и наоборот
Код

static void test(type1* var1, type2* var2) {
extern char var[sizeof(type1) == sizeof(type2)] ? 1 : -1];
var1 = var2; /* проверка присваивания указателей */
var2 = var1;
test(var2, var1); /* проверка передачи параметром */
/* другие проверки */
}

Код можно генерировать в #define вместо template, но будет генерироваться ненужный код (в C++ функцию можно объявить inline код для неё генерироваться не будет, если нет вызовов)
PM   Вверх
boostcoder
Дата 29.9.2011, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



math64, даже ваш плюсовый вариант какой-то странный...
в плюсах, этот способ будет работать везде и всегда.
Код

#include <iostream>

template<typename T1, typename T2>
struct is_same {
   static const bool value = false;
};

template<typename T1>
struct is_same<T1, T1> {
   static const bool value = true;
};

#define IS_SAME_TYPES(type1, type2) \
   extern char __##type1##_##type2##__TYPES_ARE_NOT_THE_SAME__[ \
      is_same<type1, type2>::value?1:-1 \
   ];

int main() {
   typedef char mychar;
   typedef unsigned char myuchar;
   IS_SAME_TYPES(char, mychar);
   IS_SAME_TYPES(mychar, myuchar); // error: size of array ‘__mychar_myuchar__TYPES_ARE_NOT_THE_SAME__’ is negative
}

PM WWW   Вверх
math64
Дата 29.9.2011, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Мой код непродуманный, он только иллюстрирует идею.
Ваш код лучший для C++ - он отличит даже char& от char, если убрать генерацию имени переменной из имён типов (что было сделано чтобы получить более понятное сообщение об ошибке)
PM   Вверх
mes
Дата 30.9.2011, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  29.9.2011,  17:15 Найти цитируемый пост)
  static const bool value = false;

a почему не enum ?



--------------------
PM MAIL WWW   Вверх
math64
Дата 30.9.2011, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Вот решение для C (не C++):
Код
extern void dummy(type1);
extern void dummy(type2);

Если типы type1 и type2 одинаковы, можно делать сколько угодно объявлений функции dummy
Если типы разные, перегрузка функций в C запрещена, получите ошибку.
Для того, чтобы оформить макрос, нужно придумать как сгенерировать уникальное имя функции, но такой код просто написать и без макроса. 

Это сообщение отредактировал(а) math64 - 30.9.2011, 16:22
PM   Вверх
math64
Дата 30.9.2011, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Решение как для C, так и для C++
Код
extern type1 dummy(void);
extern type2 dummy(void);

Иметь разные возвращаемые типы при одинаковых параметрах запрещено в обоих языках
PM   Вверх
boostcoder
Дата 30.9.2011, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



math64, это действительно правильное решение! держи плюс!

Добавлено @ 17:44
Код


#include <stdio.h>

#define IS_SAME_TYPES(type1, type2) \
   extern type1 __STATIC_CHECK_FOR_SAME_TYPES__##type1##_##type2##__ERROR__(); \
   extern type2 __STATIC_CHECK_FOR_SAME_TYPES__##type1##_##type2##__ERROR__();

int main() {
   typedef char mychar;
   typedef unsigned char myuchar;
   IS_SAME_TYPES(char, mychar);
   IS_SAME_TYPES(mychar, myuchar);
}

вывод:
Цитата

main.c:12:1: error: conflicting types for ‘__STATIC_CHECK_FOR_SAME_TYPES__mychar_myuchar__ERROR__’
main.c:12:1: note: previous declaration of ‘__STATIC_CHECK_FOR_SAME_TYPES__mychar_myuchar__ERROR__’ was here


Это сообщение отредактировал(а) boostcoder - 30.9.2011, 17:48
PM WWW   Вверх
math64
Дата 30.9.2011, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Для C может быть неточная работа если сравниваются указатели на функцию
Код

typedef int (*int_func)();
typedef int (*int_func_of_int)(int);
IS_SAME_TYPES(int_func, int_func_of_int);

C посчитает эти указатели совместимыми
первое определение - функция возврщает int, аргументы любые
вторая фукнция требует аргумента int

В C++ будет ошибка: первый указатель на функцию без аргументов

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1522 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.