Основное отличие заключается в том, что printf сначала получает строку формата, с заполнителями (эти знаки% вы видите), и даже может принимать некоторые параметры форматирования (например,% 2d, которые показывают 2 цифры для числа).
Вместо этого Echo отображает только строку. Когда вы делаете «$ i bar», строка сначала расширяется со значением $ i, а затем отправляется на отображаемую эхо-функцию.
При использовании сделать программы необходимо смочь к munge имя файла заранее и передать ее как макрос к gcc, который будет использоваться в программе.
В Вашем make-файле измените строку:
file.o: file.c
gcc -c -o file.o src/file.c
кому:
file.o: src/file.c
gcc "-D__MYFILE__=\"`basename $<`\"" -c -o file.o src/file.c
Это позволит Вам использовать __MYFILE__
в Вашем коде вместо __FILE__
.
Использование базового имени исходного файла ($ <) означает, что можно использовать его в обобщенных правилах, таких как ".c.o".
Следующий код иллюстрирует, как он работает.
Make-файл файла:
mainprog: main.o makefile
gcc -o mainprog main.o
main.o: src/main.c makefile
gcc "-D__MYFILE__=\"`basename $<`\"" -c -o main.o src/main.c
Файл src/main.c:
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("file = %s\n", __MYFILE__);
return 0;
}
Выполненный от оболочки:
pax@pax-desktop:~$ mainprog
file = main.c
pax@pax-desktop:~$
Отметьте "файл =" строка, которая содержит только базовое имя файла, не dirname.
Вы могли использовать:
bool IsDebugBuild()
{
return !NDEBUG;
}
Или, Вы могли использовать NDEBUG в своем Макросе для превращения включения - выключения те пути к файлам.
Мог быть сделан ТОЛЬКО программно.
возможно, это полезно...
filename = __FILE__
len = strlen(filename)
char *temp = &filename[len -1]
while(*temp!= filename)
if(*temp == '\') break;
Можно присвоиться __FILE__
к строке, и затем называют _splitpath () для разрыва частей из него. Это могло бы быть решением Windows/MSVC-only, честно я не знаю.
Я знаю, что Вы искали решение времени компиляции, и это - решение во время выполнения, но я фигурировал, так как Вы использовали имя файла, чтобы сделать (по-видимому, время выполнения) регистрацию ошибок, это могло быть простым простым способом получить Вас, в чем Вы нуждаетесь.
Можно взять __ ФАЙЛ __ и полоса от части пути, который Вы не хотите (программно). Если basedir удовлетворяет Ваши потребности, то прекрасный. Иначе получите исходный корень dir от своей системы сборки, и остальные должны быть выполнимыми.
Вы смогли делать это с шаблонным метапрограммированием, но нет никакого встроенного способа сделать это.
Править: Гм, исправление. Согласно одной странице я просто видел, GCC использует путь, который она дана для файла. Если это дало полное имя, это встроит его; если это только дало относительный, это только встроит это. Я не попробовал его сам все же.
Что делает Ваш макрос регистрации ошибок? Я предположил бы в какой-то момент, что макрос в конечном счете вызывает функцию некоторого вида, чтобы сделать вход, почему бы не, вызванная функция снимает изоляцию с компонента контура во времени выполнения?
#define LOG(message) _log(__FILE__, message)
void _log(file, message)
{
#ifndef DEBUG
strippath(file); // in some suitable way
#endif
cerr << "Log: " << file << ": " << message; // or whatever
}
Я не знаю о прямом пути. Вы могли использовать:
#line 1 "filename.c"
во главе исходного файла для устанавливания значения __FILE__
, но я не уверен, что это намного лучше, чем трудное кодирование его. или просто с помощью #define для создания собственного макроса.
Другая опция могла бы состоять в том, чтобы передать имя от Вашего Make-файла с помощью-D, и $ (окружите $ базового имени <),
Править: При использовании #define или-D опции необходимо создать собственное новое имя и не попытаться переопределить __FILE__
.
Беря идею от Glomek, это может быть автоматизировано как это:
Исходный файл x.c
#line 1 MY_FILE_NAME
#include <stdio.h>
int main(void)
{
puts(__FILE__);
return(0);
}
Строка компиляции (остерегаются одинарных кавычек вне двойных кавычек):
gcc -DMY_FILE_NAME='"abcd.c"' -o x x.c
Вывод'abcd.c
'.
Рассмотрите этот простой исходный код:
#include <stdio.h>
int main(void)
{
puts(__FILE__);
return(0);
}
На Солярисе, с GCC 4.3.1, если я компилирую это использование:
gcc -o x x.c && ./x
вывод'x.c
'Если я компилирую его использование:
gcc -o x $PWD/x.c && ./x
затем __ ФАЙЛ __ отображается на полный путь ('/work1/jleffler/tmp/x.c
'). Если я компилирую его использование:
gcc -o x ../tmp/x.c && ./x
затем __ ФАЙЛ __ отображается на'../tmp/x.c
'.
Так, в основном __ ФАЙЛ __ является путем исходного файла. Если Вы создаете с именем, Вы хотите видеть в объекте, все хорошо.
Если это невозможно (по любой причине), то необходимо будет войти в меры, предложенные другими людьми.
Та же проблема; нашел другое разрешение, просто подумал, что поделюсь им:
В файле заголовка, включенном во все мои другие файлы:
static char * file_bname = NULL;
#define __STRIPPED_FILE__ (file_bname ?: (file_bname = basename(__FILE__)))
Надеюсь, это будет полезно и для кого-то другого :)