Запретить использование функции
От: LuciferSingapore Россия  
Дата: 02.12.11 13:16
Оценка:
Есть куча кода, использующего OpenGL. Мне нужно найти все места, где используются функции OpenGL и заменить на свою реализацию.
Вот такой метод, естественно, не срабатывает:

#define glBegin(...) #pragma error Replace glBegin() with your own implementation

Хочется сделать так, чтобы при компиляции в том месте, где используется какая-либо из функций, компилятор сообщал об ошибке, желательно, с осмысленным текстом.
Можно ли это сделать при помощи препроцессора С? Если можно, то как?
Re: Запретить использование функции
От: okman Беларусь https://searchinform.ru/
Дата: 02.12.11 13:37
Оценка:
Здравствуйте, LuciferSingapore, Вы писали:

LS>Есть куча кода, использующего OpenGL. Мне нужно найти все места, где используются функции OpenGL и заменить на свою реализацию.

LS>Вот такой метод, естественно, не срабатывает:
LS>

LS>#define glBegin(...) #pragma error Replace glBegin() with your own implementation

LS>Хочется сделать так, чтобы при компиляции в том месте, где используется какая-либо из функций, компилятор сообщал об ошибке, желательно, с осмысленным текстом.
LS>Можно ли это сделать при помощи препроцессора С? Если можно, то как?

Как-то так:
my_glBegin(...)
{
    // Тут новое тело функции.
}

#define glBegin my_glBegin
Re: Запретить использование функции
От: Кодт Россия  
Дата: 02.12.11 13:38
Оценка: 6 (1)
Здравствуйте, LuciferSingapore, Вы писали:

LS>
LS>#define glBegin(...) #pragma error Replace glBegin() with your own implementation
LS>


Простой способ:
#define glBegin  _ERROR_replace_glBegin_with_your_own_implementation_

и пусть компилятор ругается на отсутствующую функцию.

Продвинутый способ:
В C99/C++0x есть оператор _Pragma() эквивалентный #pragma, только принимающий уже закавыченную (и экранированную) строку.
#define PRAGMA_ERROR(text) _Pragma( "error " text ) // text должен быть строкой
#define PRAGMA_ERROR_GL(funcname) PRAGMA_ERROR( "Please replace " #funcname " with your own implemenation" )

#define glBegin(...) PRAGMA_ERROR_GL(glBegin)
Перекуём баги на фичи!
Re[2]: Запретить использование функции
От: LuciferSingapore Россия  
Дата: 02.12.11 14:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, LuciferSingapore, Вы писали:


LS>>
LS>>#define glBegin(...) #pragma error Replace glBegin() with your own implementation
LS>>


К>Простой способ:

К>
К>#define glBegin  _ERROR_replace_glBegin_with_your_own_implementation_
К>

К>и пусть компилятор ругается на отсутствующую функцию.

Ругаться будет линкер, что не устраивает.

К>Продвинутый способ:

К>В C99/C++0x есть оператор _Pragma() эквивалентный #pragma, только принимающий уже закавыченную (и экранированную) строку.
К>
К>#define PRAGMA_ERROR(text) _Pragma( "error " text ) // text должен быть строкой
К>#define PRAGMA_ERROR_GL(funcname) PRAGMA_ERROR( "Please replace " #funcname " with your own implemenation" )

К>#define glBegin(...) PRAGMA_ERROR_GL(glBegin)
К>


А вот за это спасибо, сейчас буду пробовать!
Re[2]: Запретить использование функции
От: LuciferSingapore Россия  
Дата: 02.12.11 16:48
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Продвинутый способ:

К>В C99/C++0x есть оператор _Pragma() эквивалентный #pragma, только принимающий уже закавыченную (и экранированную) строку.
К>
К>#define PRAGMA_ERROR(text) _Pragma( "error " text ) // text должен быть строкой
К>#define PRAGMA_ERROR_GL(funcname) PRAGMA_ERROR( "Please replace " #funcname " with your own implemenation" )

К>#define glBegin(...) PRAGMA_ERROR_GL(glBegin)
К>


Оказывается, никакого #pragma error в GCC нет, там только #error. Соответственно способ не работает.
Но я добился того, чего хотел, через _Pragma("message \"Use your own glBegin\"").
Ошибку компиляции это не вызывает, но в логе сборки я могу найти все интересующие меня места в исходном тексте.

Всем спасибо.
Re[3]: Запретить использование функции
От: Кодт Россия  
Дата: 02.12.11 17:14
Оценка: 2 (1)
Здравствуйте, LuciferSingapore, Вы писали:

К>>Простой способ:

К>>
К>>#define glBegin  _ERROR_replace_glBegin_with_your_own_implementation_
К>>

К>>и пусть компилятор ругается на отсутствующую функцию.

LS>Ругаться будет линкер, что не устраивает.


Если это не голый Си, то ругаться будет всё-таки компилятор. Не надо даже объявлять эту функцию!!!
А для голого си (с умолчательным объявлением функций int f(...)) можно явно объявить функцию с уникальным типом аргумента.
typedef struct {} UNIQUE_TYPE; /* можно один тип на все функции-ошибки */
void _ERROR_replace_glBegin(UNIQUE_TYPE);
#define glBegin _ERROR_replace_glBegin

и снова будет ругаться компилятор, а до линкера дело не дойдёт.
Перекуём баги на фичи!
Re[4]: Запретить использование функции
От: LuciferSingapore Россия  
Дата: 02.12.11 18:50
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Если это не голый Си, то ругаться будет всё-таки компилятор. Не надо даже объявлять эту функцию!!!


У меня таки голый Си.
Спасибо за трюк, вроде бы очевидно, а сам додуматься не сумел
Re[4]: Запретить использование функции
От: maykie Россия  
Дата: 06.12.11 10:16
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Если это не голый Си, то ругаться будет всё-таки компилятор. Не надо даже объявлять эту функцию!!!

К>А для голого си (с умолчательным объявлением функций int f(...)) можно явно объявить функцию с уникальным типом аргумента.
К>
К>typedef struct {} UNIQUE_TYPE; /* можно один тип на все функции-ошибки */
К>void _ERROR_replace_glBegin(UNIQUE_TYPE);
К>#define glBegin _ERROR_replace_glBegin
К>

К>и снова будет ругаться компилятор, а до линкера дело не дойдёт.
Зачем так сложно?

#define glBegin(x) typedef int _ERROR_replace_glBegin[-1]


или ещё проще

#define glBegin(x) DO_NOT_USE_ME EVER

то что glBegin является вызывом ф-ции не значит, что макрос должен разворачиваться в вызов ф-ции.
Re[3]: Запретить использование функции
От: TimurSPB Интернет  
Дата: 06.12.11 10:21
Оценка:
Так вроде и в MSVC #error работает
Make flame.politics Great Again!
Re: Запретить использование функции
От: jazzer Россия Skype: enerjazzer
Дата: 06.12.11 10:42
Оценка: 4 (1)
Здравствуйте, LuciferSingapore, Вы писали:

LS>Есть куча кода, использующего OpenGL. Мне нужно найти все места, где используются функции OpenGL и заменить на свою реализацию.

LS>Вот такой метод, естественно, не срабатывает:
LS>

LS>#define glBegin(...) #pragma error Replace glBegin() with your own implementation

LS>Хочется сделать так, чтобы при компиляции в том месте, где используется какая-либо из функций, компилятор сообщал об ошибке, желательно, с осмысленным текстом.
LS>Можно ли это сделать при помощи препроцессора С? Если можно, то как?

Если речь идет о GCC, то никакого препроцессора не надо, просто объяви ее с соответствующим атрибутом:
void glBegin(GLenum) __attribute__((error("Replace glBegin() with your own implementation")));


Сообщение об ошибке будет таким:
error: call to 'glBegin' declared with attribute error: Replace glBegin() with your own implementation


warning делается аналогично.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Запретить использование функции
От: Кодт Россия  
Дата: 06.12.11 19:34
Оценка:
Здравствуйте, maykie, Вы писали:

M>Зачем так сложно?

M>
M>#define glBegin(x) typedef int _ERROR_replace_glBegin[-1]
M>

Если glBegin идёт не отдельным стейтментом, а в составе другого стейтмента — например,
if(glBegin(), is_it_ok) {...}

получится адский ад

M>или ещё проще

M>
M>#define glBegin(x) DO_NOT_USE_ME EVER
M>

M>то что glBegin является вызывом ф-ции не значит, что макрос должен разворачиваться в вызов ф-ции.

Как и с необъявленной функцией, — компилятор выругается ровно один раз на всю единицу компиляции, про несуществующую переменную типа int.

Так что мой последний вариант с несовпадающими аргументами, либо ад с тайпдефом, — более предпочтительны.
Перекуём баги на фичи!
Re: Запретить использование функции
От: dmitry_npi Россия  
Дата: 07.12.11 06:45
Оценка: 2 (1)
Здравствуйте, LuciferSingapore, Вы писали:

1) Объявить функцию deprecated. В VC++ — __declspec(deprecated). В gcc — __attribute__(warning)
2) Настроить это предупреждение как ошибку.

А если только gcc, еще лучше: __attribute__(error)
Атмосферная музыка — www.aventuel.net
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.