błąd: nieznana nazwa typu „bool”

86

Pobrałem kod źródłowy i chciałem skompilować plik skanera. Generuje ten błąd:

[meepo@localhost cs143-pp1]$ gcc -o lex.yy.o lex.yy.c -ll
In file included from scanner.l:15:0:
scanner.h:59:5: error: unknown type name ‘bool’
In file included from scanner.l:16:0:
utility.h:64:38: error: unknown type name ‘bool’
utility.h:74:1: error: unknown type name ‘bool’
In file included from scanner.l:17:0:
errors.h:16:18: fatal error: string: No such file or directory
compilation terminated.

Próbowałem użyć innego narzędzia do kompilacji, ale pojawiły się różne błędy.

[meepo@localhost cs143-pp1]$ g++ -o scan lex.yy.c -ll
/usr/bin/ld: cannot find -ll
collect2: ld returned 1 exit status

Mój system operacyjny to 3.0-ARCH, nie wiem, dlaczego tak się stało. Jak naprawić błąd?

Meepo
źródło
12
#include <stdbool.h>
leppie

Odpowiedzi:

146

C90 nie obsługuje logicznego typu danych.

C99 zawiera to w tym:

#include <stdbool.h>
user978122
źródło
48
C99 tak, jeśli masz #include <stdbool.h>.
Keith Thompson,
1
C99 ma natywny typ boolowski o nazwie _Bool. <stdbool.h>Nagłówek zapewnia typedef za to nazwie bool, wraz z truea false.
MM
1
jak to możliwe, że mogę dobrze skompilować moje rzeczy bool na OSX bez dołączania stdbool.h?
David 天宇 Wong
Skopiowałem i wkleiłem trochę kodu "C" i zgodnie z odpowiedzią musiałem dołączyć gccskompilowany plik stbool.h . Jednak wydaje się, że C ++ zna wartości logiczne „po wyjęciu z pudełka”, więc mógłbym po prostu użyć go g++do kompilacji bez żadnych zmian w kodzie. Więc w zależności od kontekstu, źródła kodu i dalszych błędów, być może nie patrzysz na kod C, ale C ++.
nuala
55

C99 tak, jeśli masz

#include <stdbool.h> 

Jeśli kompilator nie obsługuje C99, możesz to zdefiniować samodzielnie:

// file : myboolean.h
#ifndef MYBOOLEAN_H
#define MYBOOLEAN_H

#define false 0
#define true 1
typedef int bool; // or #define bool int

#endif

(ale należy pamiętać, że ta definicja zmienia ABI dla booltypu, więc łączenie z zewnętrznymi bibliotekami, które zostały skompilowane z odpowiednio zdefiniowanymi, boolmoże spowodować trudne do zdiagnozowania błędy w czasie wykonywania).

Tomasz
źródło
39
Moim ulubionym sposobem definiowania booljest:typedef enum { false, true } bool;
Keith Thompson
2
Musisz typedefmieć możliwość odniesienia się do typu jako boolzamiast enum bool.
Keith Thompson
3
Ten drugi sposób jest z natury ryzykowny, ponieważ nie ma niejawnej konwersji. Na przykład, gdybyśmy mieli 16-bitowe liczby int, a long FLAG = 0x4000000; bool b = ( x & FLAG );to powoduje niezdefiniowane zachowanie (z prawdopodobnym wynikiem, który bbędzie wyglądał na fałsz, nawet jeśli xustawiono flagę). Trudniej to zauważyć, gdy booljest to parametr funkcji. Używaj, ale używaj ostrożnie.
MM
6
Strzec się! Nie typedef będzie to zachowywało się tak samo, jak prawdziwy bool C99 w przypadkach skrajnych, zarówno dlatego, że prawdziwy bool C99 ma tylko dwie wartości, ale typedefobsługuje tak wiele, jak introbi, ale także dlatego, że C99 boolma specjalne reguły rzutowania, których typedefnie ma. Przykład: w C99 (bool)99999998430674944jest jednoznacznie true. Z twoją typedefkompilacją w GCC na moim komputerze (bool)99999998430674944jest false(ze względu na sposób obsługi przepełnienia podczas rzutowania).
Mark Amery
1
@KeithThompson Definicja taka jak ta przerywa ABI, jeśli spróbujesz połączyć się z zewnętrzną biblioteką, która została skompilowana z normalnym bool.
yugr
5

Po prostu dodaj następujące informacje:

#define __USE_C99_MATH

#include <stdbool.h>
M.Hefny
źródło
2
Co to jest __USE_C99_MATH?
Keith Thompson
4

Gdzieś w twoim kodzie jest linia #include <string>. To samo w sobie mówi, że program jest napisany w C ++. Więc używanie g++jest lepsze niż gcc.

W przypadku brakującej biblioteki: powinieneś rozejrzeć się po systemie plików, czy możesz znaleźć plik o nazwie libl.so. Użyj locatepolecenia, spróbuj /usr/lib, /usr/local/lib, /opt/flex/liblub użyj brute-force find / | grep /libl.

Po znalezieniu pliku musisz dodać katalog do wiersza poleceń kompilatora, na przykład:

g++ -o scan lex.yy.c -L/opt/flex/lib -ll
Roland Illig
źródło