Итак, если я правильно понимаю, ваша мотивация заключается в том, что у вас есть существующий код, который выглядит как
p = bar(1,2);
, и вы хотите определить макросы, чтобы он вместо этого вызывал foo(1,2)
. Но вы не хотите изменять исходный файл, чтобы включить объявление foo
- вы хотите делать все с помощью определений макросов командной строки. Я правильно понял?
Поскольку вы отметили это g cc, возможно, вы хотите рассмотреть нестандартные расширения g cc для языка C. Если это так, вы можете сделать это с помощью выражений операторов g cc , которые также поддерживаются clang и i cc. Определите bar
для расширения до выражения, содержащего блок, который объявляет foo
и значение которого является указателем на foo
. То есть:
#define bar ({ extern void *foo(int, int); foo; })
Или из командной строки:
gcc -D'bar=({ extern void *foo(int, int); foo; })' call_bar.c
Попробуйте на Godbolt .
Это имеет
Вариантом было бы определение макроса bar(a,b)
с двумя аргументами, где соответствующее выражение оператора фактически вызывает foo
:
gcc -D'bar(a,b)=({ extern void *foo(int, int); foo((a), (b)); })' call_bar.c
, но это не удастся, если исходный код попытается вызвать p = (bar)(a,b)
или пытается взять адрес bar
.
Я не знаю никакого способа получить такой точный эффект в стандартном C. Но другой подход - создать файл заголовка, содержащий объявление foo
, а затем использовать -include
, чтобы «вставить» его в верхнюю часть исходного файла:
gcc -include declare_foo.h -Dbar=foo call_bar.c
This isn ' Технически это то, о чем вы просили, потому что на каком-то уровне это подразумевает объявление foo
«заранее», но это все равно может помочь решить вашу проблему. В этом случае все стандартно C, но мы перенесли «непереносимость» из кода в процесс сборки.
С другой стороны, если желаемая замена на bar
это что-то достаточно простое, чтобы вставить макрос, например, постоянный возврат в вашем примере, тогда вы можете вырезать посредника foo
и просто определить макрос:
gcc -D'bar(a,b)=((void *)0xbadcafe)' call_bar.c