2013-05-03 5 views
1

я не знаю, если название темы точно вводит мою проблему, но главное: в моем коде компаний , есть функция, например:ищет макрос, который заменит функцию

float func_x(float a){ 
     float b 
     return b 
} 

что функция occuers примерно в 1000 мест. Теперь новая функция была добавлена:

void func_x2(void *a, void *b){ 
    do sth 
} 

Эта функция должна заменить все occuerences из func_x в коде, так что изменения должны происходить из (псевдокод):

float p = 123.33; 
float x = func_x(p) 
to: 
float x; 
float p = 123.33; 
func_x2((void *)&p, (void*)&x); 

Мой вопрос: ли это даже возможно написать макрос C (даже очень сложный), который заменит func_x на func_x2, поэтому код не изменится вообще? Кто-нибудь пытался это сделать?

С уважением J

+10

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

+7

Слава Богу, я не работаю для вашей компании. Просто удалите исходную функцию и вручную исправьте 1000 мест, которые она вызывается. 1000 мест не так много. Это одноразовая работа, и код будет оставлен в гораздо лучшем состоянии, чем если бы вы использовали какой-то макро-хакер. Раньше мне приходилось поддерживать такой код, это кошмар. – john

+3

Возможно, но это не лучшая практика. Время, «спасенное» от этого, будет потеряно 10 раз за его поддержание. –

ответ

4

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

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

+2

Самый простой пример: 'float x = func_x (1.0f) + func_x (2.0f);' – MSalters

0

Точно, что вы хотите, невозможно. Вы могли бы переименовать/удалить оригинальный func_x и заменить его функцией, которая просто вызывает func_x2.

0

Одна из идей - использовать регулярное выражение для замены всех вхождений старой функции.

Это регулярное выражение улавливает пример, приведенный в вопросе

^.*?\s(.*)\s*=\s*func_x\(\s*(.*)\) 

, а затем вы можете использовать что-то вроде этого, чтобы заменить его

float \2;\nfunc_x2\(\(void \*\)&\2, \(void\*\)&\1\) 

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

+1

- плохая идея, потому что функция имеет побочные эффекты, и вам нужно убедиться, что вы вводите новые переменные в нужном месте. – TemplateRex

+0

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

4

Я понятия не имею, из того, что функции действительно, но в случае x2 просто расширение х, вы могли бы сделать что-то подобное

float func_x(float a){ 
    float b; 
    func_x2((void *)&a, (void *)&b); 
    return b; 
} 
+1

Согласитесь с этим. Я предполагаю, что 'func_x2' - это какой-то древний, проверенный на практике код, потому что все остальное не оправдывало бы этот ужасный интерфейс. И правильный способ справиться с таким старым зверьком - это вставить правильное типичный интерфейс, вот так. – MSalters

0

не представляется возможным, так как вы пытаетесь модифицировать определение функции и ее реализацию.