LINUX.ORG.RU

Интерпретация «C» в rootcint.


0

1

Коротко и без воды:

rootcint позволяет интерпритировать C/C++ если в сишный файл добавить

#! /usr/bin/rootcint
То он соотвецтвенно и исполняется как обычный скрипт, но компилить не убрав строку не прокатит, есть ли вариант иметь сишный файл и не трогая его исполнять как скрипт и компилиовать.

★★★★★

Очевидно, что без прокладки никак. С прокладкой - пусть она удаляет первую строку, если она такая, по потом скармливает gcc.

P. S. Просто ради интереса: а зачем сишные скрипты интерпретировать?

Kroz ★★★★★
()
Ответ на: комментарий от netcat

Отлаживать легче, нет?

Каким образом? Это ж то же самое что и
$ gcc proga.cpp && ./a.out
разве нет? Ну, с точки зрения результата?

Kroz ★★★★★
()

а если rootcint /путь.к.файлу.c? не прокатит?

xsektorx ★★★
()
Ответ на: комментарий от Stil

по крайней мере с вещами типа

#if 0
#!/bin/bash
gcc test.c -o test
#endif

работает

Stil ★★★★★
()
Ответ на: комментарий от Kroz

Интерпретатор подразумевает последовательное выполнение инструкций, так что в случае сбоя он сразу выведет описание ошибки, имя файла и строку, где она произошла. При использовании компилятора придется запускать отладчик. Разумеется, не забыв скомпилировать программу с опцией -g.

netcat ★★
()
Ответ на: комментарий от netcat

так что в случае сбоя он сразу выведет описание ошибки

Сбоя??? Какого сбоя?

- Если проблема в синтаксисе, код не скомпилируется (ваш, К. О.)
- Если проблема в логике, то ни один интерпретатор/дебаггер не скажет тебе об этом, ибо, возможно, ты хотел такую логику.
- Если деление на ноль, переполнение памяти и т. п. - ок, здесь может быть профит. Но лично я предпочитаю чтобы в таких случаях меня жестко били по голове, ибо если мой моск придумывает алгоритмы с такими вот эффектами, то мне нужно провести работу хорошую над ошибками: вчитаться в код, понять где это, впитать этот опыт и больше такого не делать. Благо, такого у меня почти никогда не встречается.
- Если не поймано исключение, то это твой недочет, так как в коде с исключениями в самой «первой» функции можно ловить все исключения и писать в stderr что-то типа «Error in source code».

Единственное, чем может быть полезна среда разработки - это расстановка break-point'ов и пошаговая трассировка с отслеживанием значений переменных. Но интерпретатор здесь не поможет.

Или как?

Kroz ★★★★★
()
Ответ на: комментарий от vertexua

man sh:

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

То, что оно работает говорит только о том, что либо документация врёт, либо что это неопределённое поведение.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

Хотя, если вдуматся, то из `man sh' выходит, что всё, на что execve(2) вернул ENOEXEC, будет интерпретированно как shell script.

Таким образом

#if 0
#!/bin/bash
gcc test.c -o test
#endif
работать будет (`#!/bin/bash' не несёт тут никакой смысловой нагрузки и является просто напросто комментарием), а вот
#if 0
#!/usr/bin/rootcint
#endif
уже работать не будет, из-за перечисленных выше причин. (shebang должен начитаться с нулевого байта)

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 2)

А на кой тебе интерпретировать обязательно с шебангом? Вызывай rootcint явным образом.

anonymous
()
Ответ на: комментарий от Kroz

Ты вообще хотя бы одним скриптовым языком пользовался, или так, диванный терететик и тупо погулять вышел?

anonymous
()
Ответ на: комментарий от anonymous

А ты ради интереса поиграй с ROOT. Там C++ - интерактивный язык.

Зачем мне это?

Kroz ★★★★★
()
Ответ на: комментарий от anonymous

Не то же самое. Скрипты исполняются построчно.

Спасибо, К. О.
Меня интересует профит с точки зрения отладки программ.

Kroz ★★★★★
()
Ответ на: комментарий от anonymous

Ты вообще хотя бы одним скриптовым языком пользовался, или так, диванный терететик и тупо погулять вышел?

Толлить - в токсы. Есть что сказать по делу - говори.

P. S. bash, JS, PHP.

Kroz ★★★★★
()
Ответ на: комментарий от beastie

спасибо за развернутый ответ. серьезно.

Stil ★★★★★
()
Ответ на: комментарий от Kroz

Возьмем, к примеру, Python:

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 перейдет в интерактивный режим, очень полезный для отладки. Можно, например, посмотреть как себя ведет та или иная функция, если ей передать разные параметры.
Это я сходу пример привел, выгоды на самом деле больше.

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

Не все так круты, и не всем нравится, когда их «бьют по голове».

netcat ★★
()
Последнее исправление: netcat (всего исправлений: 2)
Ответ на: комментарий от Stil

#if 0

не. sha-bang должна быть ПЕРВОЙ строкой. Не взлетит.

drBatty ★★
()
Ответ на: комментарий от beastie

Хотя, если вдуматся, то из `man sh' выходит, что всё, на что execve(2) вернул ENOEXEC, будет интерпретированно как shell script.

ага. Потому в принципе можно написать shell скрипт, который на самом деле делает exec /usr/bin/rootcint, который выполняет этот скрипт уже как сишный код. Но зачем?

drBatty ★★
()
Ответ на: комментарий от netcat

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

Это с технической точки зрения.

С точки зрения подхода, ИМХО, это применимо только для небольших скриптов для себя; в продакшн такой код идти не должен. Проверка допустимых значений, кодов возвратов и обработка любых подобных событий должна выполняться самой программой, и это MustBe. Я, когда пишу код, стараюсь это делать сразу, или хотя бы помечать как // TODO (писать кучу if'ов действительно скучно). Но, это мое ИМХО и я него не собираюсь навязывать.

Еще раз, по твоему запросу, могу только посоветовать:
1. Написать «прокладку» на bash, которая перед компиляцией будет отрезать первую строку.
2. Если интересно, то в Линукс можно сделать привязку по контенту. Например, запустив ./program.cpp, если этот файл начинается, например с «// interpret it», то оно скормит интерпретатору; ну, а с++ восприймет первую строку просто как комментарий.
3. Если интересно, функционал, который ты привел в примере, я обеспечивал в самом коде средствами C++. Могу рассказать логику.

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

3. Если интересно, функционал, который ты привел в примере, я обеспечивал в самом коде средствами C++. Могу рассказать логику.

Это интересно - расскажи.

netcat ★★
()
Ответ на: комментарий от anonymous

Огромное спасибо, надо покопатся в нём, историю успеха отпишу если успех будет.

Dron ★★★★★
() автор топика
Ответ на: комментарий от netcat

Это интересно - расскажи.

Рассказываю логику. К коду не придирайся.

Объект-локальная переменная в функции уничтожается при выходе из функции. Соответственно, первое действие функции - создание объекта:

void function1()
{
CDebug log("function1");
...
}

В классе CDebug в конструктора пишем что-то типа:

class CDebug{
public:
  static ??? container;
  string function;

  CDebug(string fn){
    CDebug::container << string("Entering ") + fn;
    function=fn;
  }
  ~CDebug(){
    CDebug::container << string("Exiting ") + function;
  }
  ...
}

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

Какой контейнер - придумай сам. Это может быть лог-файл (у меня так было, потом писал тулзовину, которая показывала ход программы), просто буфер в памяти, который потом будет выводить стек функций, как в твоем примере. Контейнер - статический, чтобы все объекты класса имели один контейнер.

Далее используем силу макросов. Например, так: #define DEBUG(f) CDebug log(f);

Так: #define RETURN(s) log.Error(s);return;

Можно задействовать __LINE__ , __FILE__ для того чтобы понимать, где произошла ошибка.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 3)
Ответ на: комментарий от netcat

Если честно, думал, что тебя больше заинтересует второй пункт в моем списке: по-моему это то, что тебе нужно. Просто еще раз обращаю внимание.

Kroz ★★★★★
()
Ответ на: комментарий от AptGet

в С open() не бросает исключение, интерпретатор тут никак не поможет, трейса не будет.

В С - да, не бросает; поможет только стопка if'ов. В С++ AFAIK бросает.

P. S. Исключения, AFAIK, это вообще фишка C++ . За что его и люблю :) .

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)

немножко офтопа. поставил rootcint первый раз. а что это он вываливает вот такую лапшу

// File generated by /usr/bin/rootcint ...
в мане нет ключа типа --quiet

punya ★★
()
Последнее исправление: punya (всего исправлений: 1)

есть ли вариант иметь сишный файл и не трогая его исполнять как скрипт и компилиовать.

#!/usr/bin/tcc -run
#include <stdio.h>

int main() 
{
    printf("Hello World\n");
    return 0;
}

tcc сейчас пилится тут:

http://repo.or.cz/w/tinycc.git

wota ★★
()
Ответ на: комментарий от anonymous

И это действительно вариант, но отчасти конечно

дополняем файл исходника

#! /usr/bin/tcc -run
и он исполняется более не изменяя его можно компилировать
tcc mainc

Но это конечно если пользоваться лишь tcc как штатным компилятором что не совсем мне подходит и также остаётся трабла с gcc & clang

Dron ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.