gcc выдает .o но bash говорит неизвестную команду - PullRequest
3 голосов
/ 28 мая 2011

Редактировать: я исправил несколько вещей, которые были указаны, но реальная проблема остается нерешенной.

Этот скрипт bash:

set -vx

/usr/bin/llvm-gcc-4.2 -ansi -g -o mytest mytest.c 
ls -l mytest
./mytest
file mytest

производит такой вывод:

/usr/bin/llvm-gcc-4.2 -ansi -g -o mytest mytest.c 
++ /usr/bin/llvm-gcc-4.2 -ansi -g -o mytest mytest.c
ls -l mytest
++ ls -l mytest
-rwxr-xr-x  1 jimslager  wheel  37496 May 27 17:26 mytest
./mytest
++ ./mytest
error: unknown command ./mytest
file mytest
++ file mytest
mytest: Mach-O 64-bit executable x86_64

Я извлек это из чего-то большего, чем пользуюсь несколько месяцев, но никогда не видел такого результата.Как gcc может создать объект без ошибок или предупреждений, но объект неизвестен?

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

Редактировать: вот код.Извините, что так долго.

/* Test Exercise 5-10: Write the program myexpr, which evaluates a reverse Polish expression from the command line, where each operator or operand is a separate argument.  For example,
 *      expr 2 3 4 + *
 * evaluates 2 x (3+4).
 * */
#include <stdio.h>
#include <string.h>
#define MAXLINE 68
#define TABSIZE 8
#define TAB '`'
#define SPACE '-'
#define NEW '\\'
#define TRUE 1
#define FALSE 0
#define IN 1
#define OUT 0
#define FOLDLENGTH 20
#define MAXLEN 12
#define SMALLER(i, j) ((i) > (j) ? (j) : (i))
#define N(c) (c=='\0' ? '\\' : c)

/* #include "subs.c" */

#define MAXOP 100 /* max size of operand or operator */ 
#define NUMBER '0' /* signal that a number was found */

int getop(char []); 
void push(double); 
double pop(void);
double top(void);
void dup(void);
void clear(void);
void stackswap(void);
double atof(char s[]);
int myisdigit(char c);
int myisspace(char c);

/* reverse Polish calculator */ 
int main(int argc, char *argv[]) 
{
    int type; 
    double op2; 
    char s[MAXOP];

    while (--argc>0) 
        while (type = getop(&(*++argv[0])))
printf("Just after while: type = %d, *argv[0] = %s\n", type, *argv);
        switch (type) {
        case NUMBER: 
            push(atof(*argv));
printf("NUMBER: atof(*argv[0]) = %g, *argv[0] = %s\n", atof(*argv), *argv);
            break; 
        case '+':
printf("+ detected\n");
            push(pop() + pop());
            break; 
        case '*':
printf("* detected\n");
            push(pop() * pop()); 
            break; 
        case '-':
printf("- detected\n");
            op2 = pop(); 
            push(pop() - op2);
            break;
        case '/': 
printf("/ detected\n");
            op2 = pop();
            if (op2 != 0.0) 
                push(pop() / op2);
            else
                printf("error: zero divisor\n"); 
            break;
        case '%': 
printf("Modulo detected\n");
            op2 = pop();
            if (op2 != 0.0) 
                push((int) pop() % (int) op2);
            else
                printf("error: zero divisor\n"); 
            break;
        case 't':
printf("t detected\n");
            printf("%g\n", top());
            break; 
        case 'd':
printf("d detected\n");
            dup();

            break; 
        case 's': 
printf("s detected\n");
            stackswap();
            break;
        case 'c':
printf("c detected\n");
            clear();
            break;
        case '\n': 
printf("\\n detected\n");
            printf("\t%.8g\n", pop()); 
            break;
        default: 
            printf("error: unknown command %s\n", *argv); 
            break;
        }
     return 0;
}

#define MAXVAL 100 /* maximum depth of val stack */

int sp = 0; /* next free stack position */ 
double val[MAXVAL]; /* value stack */

/* push: push f onto value stack */ 
void push(double f) 
{
printf("push: Started.   f = %g, sp = %d\n", f, sp);
    if (sp < MAXVAL) 
        val[sp++] = f;
    else
        printf("error: stack full, can't push %g\n", f);
printf("push: Finished.  f = %g, sp = %d\n", f, sp);
}

/* dup: duplicate top of stack */ 
void dup(void) 
{
printf("dup: Started.   top = %g, sp = %d\n", top(), sp);
    push(top());
printf("dup: Finished.   top = %g, sp = %d\n", top(), sp);
}

/* pop: pop and return top value from stack */ 
double pop(void) 
{
printf("pop: sp = %d, val[--sp] = %g\n", sp, val[sp-1]);
    if (sp > 0) 
        return val[--sp];
    else { 
        printf("error: stack empty\n"); 
        return 0.0;
    }
}

/* top: return top value from stack without changing sp */ 
double top(void) 
{
printf("top: sp = %d, val[0] = %g\n", sp, val[0]);
    if (sp > 0) 
        return val[sp-1];
    else { 
        printf("error: stack empty\n"); 
        return 0.0;
    }
}

/* stackswap: swap the top 2 values in stack */
void stackswap(void)
{
printf("Starting stackswap: val[sp-1] = %g, val[sp-2] = %g\n", val[sp-1], val[sp-2]);
    double op2, op3;
    op2 = pop();
    op3 = pop();
    push(op2);
    push(op3);
printf("Finishing stackswap: val[sp-1] = %g, val[sp-2] = %g\n", val[sp-1], val[sp-2]);
}

/* clear: clear the stack */
void clear(void)
{
    sp = 0;
}

int getch(void); 
void ungetch(int);

/* getop: get next character or numeric operand */ 
int getop(char s[]) 
{
    int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t')
        ;
    s[1] = '\0'; 
    if (!isdigit(c) && c != '.')
        return c; /* not a number */
    i = 0;
    if (isdigit(c)) /* collect integer part */ 
        while (isdigit(s[++i] = c = getch()))
            ;
    if (c=='.') /* collect fraction part */
        while (isdigit(s[++i] = c = getch())) ;
    s[i] = '\0'; 
    if (c != EOF)
        ungetch(c); 
    return NUMBER;
}

#define BUFSIZE 100

char buf[BUFSIZE];  /* buffer for ungetch */ 
int bufp = 0;   /* next free position in buf */

int getch(void) /* get a (possibly pushed-back) character */ 
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) /* push character back on input */ 
{
    if (bufp >= BUFSIZE) 
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

/* atof: convert s to double */
double atof(char s[])
{
    double val, power, epower, d; 
    int i, j, sign, esign=0, eval;
printf("atof: s = %s\n", s);

    for (i = 0; myisspace(s[i]); i++); /* skip white space */

    sign = (s[i] == '-') ? -1 : 1; /* Determine sign and strip it */
    if (s[i] == '+' || s[i] == '-')
        i++; 

    for (val = 0.0; myisdigit(s[i]); i++) /* Determine value before dec point */
        val = 10.0 * val + (s[i] - '0'); 

    if (s[i] == '.')
        i++; 

    for (power = 1.0; myisdigit(s[i]); i++) { /* include value after dec */
        val = 10.0 * val + (s[i] - '0'); 
        power *= 10;            /* power is where . goes */
    } 

    if (s[i]=='e' || s[i]=='E') { /* Exponential form */

        esign = (s[++i]=='-') ? -1 : 1; /* Sign of exponent */
        if (s[i]=='+' || s[i]=='-')
            i++;

        for (epower=0.1, eval=0.0; myisdigit(s[i]); i++) { /* Determine exponent */
            eval = 10*eval + (s[i]-'0');
            epower *= 10;
        }
    }

    d = (sign*val / power);     /* Place dec point in mantissa */

    if (esign!=0) {         /* If exp form then adjust exponent */
        for (j=1; j<=eval; j++) {
            d = (esign==1 ? d*10.0 : d/10.0);
        }
    }
    return (d);
}

/* Determine is c is a digit */
int myisdigit(char c)
{
    if (c>='0' && c<='9') 
        return TRUE;
    else 
        return FALSE;
}

/* Returns 1 if c is whitespace, 0 otherwise */
int myisspace(char c)
{
    return ((c==' ' || c=='\n' || c=='\t') ? 1 : 0); 
}

Ответы [ 5 ]

6 голосов
/ 28 мая 2011

Вероятно, это должно быть ./test.o для его запуска.Как правило, системы UNIX не имеют "."(текущий каталог) в PATH по умолчанию.

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

4 голосов
/ 28 мая 2011

Сделайте последнюю строку ./test.o и все должно работать.

Если вы указываете только имя файла, но не путь, тогда будут учитываться только пути поиска, и ваш текущий рабочий каталог в большинстве случаев не является их частью (или, скорее, определенно нет, втвой пример).

3 голосов
/ 28 мая 2011
  1. . отсутствует в $PATH, поэтому необходимо указать путь к файлу../test.o

  2. .o файлы обычно не исполняются;они должны быть связаны, прежде чем они могут быть запущены.Хотя здесь дело не в этом.

2 голосов
/ 28 мая 2011

Возможно, локальный каталог не находится в вашем пути (и вы не хотите, чтобы он был). Вы должны быть в состоянии запустить его с ./test.o. Кроме того, суффикс .o здесь странный. У вас есть динамически связанный исполняемый файл, а не объектный файл. (Попробуйте file test.o.) В Unix те, у кого обычно нет расширения, в Windows обычно имеют расширение .exe.

0 голосов
/ 28 мая 2011

Doh!Мне наконец пришло в голову, что здесь происходит.Эта программа является упражнением 5-10 от K & R, которое состоит в том, чтобы пересмотреть калькулятор обратного польского на странице 76, чтобы получить его ввод из командной строки, а не из stdin.Я делал это, когда получил сообщение «неизвестная команда» и подумал, что оно исходит от компилятора, но на самом деле оно исходит из моего собственного кода!

Теперь я вернусь и изменю его так, чтобы префикс всех сообщений об ошибках с argv [0] (и использовал это с этого момента), чтобы эта ошибка больше никогда не повторялась.

...