rootcint позволяет интерпритировать C/C++ если в сишный файл добавить
#! /usr/bin/rootcint
То он соотвецтвенно и исполняется как обычный скрипт, но компилить не убрав строку не прокатит, есть ли вариант иметь сишный файл и не трогая его исполнять как скрипт и компилиовать.
Интерпретатор подразумевает последовательное выполнение инструкций, так что в случае сбоя он сразу выведет описание ошибки, имя файла и строку, где она произошла. При использовании компилятора придется запускать отладчик. Разумеется, не забыв скомпилировать программу с опцией -g.
так что в случае сбоя он сразу выведет описание ошибки
Сбоя??? Какого сбоя?
- Если проблема в синтаксисе, код не скомпилируется (ваш, К. О.) - Если проблема в логике, то ни один интерпретатор/дебаггер не скажет тебе об этом, ибо, возможно, ты хотел такую логику. - Если деление на ноль, переполнение памяти и т. п. - ок, здесь может быть профит. Но лично я предпочитаю чтобы в таких случаях меня жестко били по голове, ибо если мой моск придумывает алгоритмы с такими вот эффектами, то мне нужно провести работу хорошую над ошибками: вчитаться в код, понять где это, впитать этот опыт и больше такого не делать. Благо, такого у меня почти никогда не встречается. - Если не поймано исключение, то это твой недочет, так как в коде с исключениями в самой «первой» функции можно ловить все исключения и писать в stderr что-то типа «Error in source code».
Единственное, чем может быть полезна среда разработки - это расстановка break-point'ов и пошаговая трассировка с отслеживанием значений переменных. Но интерпретатор здесь не поможет.
If the program is not a normal
executable file (i.e., if it does not begin with the «magic number» whose ASCII representation is «#!», so
execve(2) returns ENOEXEC then) the shell will interpret the program in a subshell.
man bash:
If the program is a file beginning with #!, the remainder of the first line specifies an interpreter for the
program.
man ksh:
[…] execve(2) fails to execute
and which do not start with a ``#!shell" sequence
То, что оно работает говорит только о том, что либо документация врёт, либо что это неопределённое поведение.
def get_text():
f = open('/etc/blahblahblah') #файла-то нет
text = f.readlines()
f.close()
return text
def print_text():
text = get_text()
print(text)
print_text()
Результат:
Traceback (most recent call last):
File "bug.py", line 11, in <module>
print_text();
File "bug.py", line 8, in print_text
text = get_text()
File "bug.py", line 2, in get_text
f = open('/etc/blahblahblah')
IOError: [Errno 2] No such file or directory: '/etc/blahblahblah'
Информативно и не надо возиться с отладчиком. А еще можно запустить python с ключом -i, тогда после выполнения скрипта python перейдет в интерактивный режим, очень полезный для отладки. Можно, например, посмотреть как себя ведет та или иная функция, если ей передать разные параметры.
Это я сходу пример привел, выгоды на самом деле больше.
лично я предпочитаю чтобы в таких случаях меня жестко били по голове, ибо если мой моск придумывает алгоритмы с такими вот эффектами, то мне нужно провести работу хорошую над ошибками: вчитаться в код, понять где это, впитать этот опыт и больше такого не делать. Благо, такого у меня почти никогда не встречается.
Не все так круты, и не всем нравится, когда их «бьют по голове».
Хотя, если вдуматся, то из `man sh' выходит, что всё, на что execve(2) вернул ENOEXEC, будет интерпретированно как shell script.
ага. Потому в принципе можно написать shell скрипт, который на самом деле делает exec /usr/bin/rootcint, который выполняет этот скрипт уже как сишный код. Но зачем?
Соглашусь, удобно. Раньше такой функционал обеспечивали среды разработки, сейчас... сейчас я просто ими не пользуюсь, все как-то не доходят руки выбрать.
Это с технической точки зрения.
С точки зрения подхода, ИМХО, это применимо только для небольших скриптов для себя; в продакшн такой код идти не должен. Проверка допустимых значений, кодов возвратов и обработка любых подобных событий должна выполняться самой программой, и это MustBe. Я, когда пишу код, стараюсь это делать сразу, или хотя бы помечать как // TODO (писать кучу if'ов действительно скучно). Но, это мое ИМХО и я него не собираюсь навязывать.
Еще раз, по твоему запросу, могу только посоветовать: 1. Написать «прокладку» на bash, которая перед компиляцией будет отрезать первую строку. 2. Если интересно, то в Линукс можно сделать привязку по контенту. Например, запустив ./program.cpp, если этот файл начинается, например с «// interpret it», то оно скормит интерпретатору; ну, а с++ восприймет первую строку просто как комментарий. 3. Если интересно, функционал, который ты привел в примере, я обеспечивал в самом коде средствами C++. Могу рассказать логику.
Что имеем: при входе в каждую функцию делается запись, что мы в нее вошли, при выходе - что вышли.
Какой контейнер - придумай сам. Это может быть лог-файл (у меня так было, потом писал тулзовину, которая показывала ход программы), просто буфер в памяти, который потом будет выводить стек функций, как в твоем примере. Контейнер - статический, чтобы все объекты класса имели один контейнер.
Далее используем силу макросов. Например, так:
#define DEBUG(f) CDebug log(f);
Так:
#define RETURN(s) log.Error(s);return;
Можно задействовать __LINE__ , __FILE__ для того чтобы понимать, где произошла ошибка.