Странная ошибка gcc: бродячий '\NNN' в программе

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

У двух моих пользователей есть ошибки компилятора (gcc), которые выглядят так:

/home/someone/Source/src/._regex.cpp:1:1: warning: null character(s) ignored
/home/someone/Source/src/._regex.cpp:1: error: stray ‘\5’ in program
/home/someone/Source/src/._regex.cpp:1: error: stray ‘\26’ in program
/home/someone/Source/src/._regex.cpp:1: error: stray ‘\7’ in program
/home/someone/Source/src/._regex.cpp:1:5: warning: null character(s) ignored
/home/someone/Source/src/._regex.cpp:1: error: stray ‘\2’ in program
...

Я не могу воспроизвести эти ошибки; код отлично компилируется на всех машинах, которые я тестировал.

Поиск в Google, казалось, показал, что это часто является результатом странной кодировки или странного форматирования, но я прогнал весь исходный код через шестнадцатеричный редактор, и все символы являются либо печатными ASCII (0x20 - 0x7E), либо табуляцией, либо новой строкой. Вот и все.

Также оба пользователя успешно скомпилировали предыдущую версию библиотеки; но конкретный рассматриваемый файл (regex.cpp) и его заголовочные файлы с тех пор не изменялись!

Подробнее см. здесь, включая ссылки для скачивания. код, если хотите. Но я был бы рад просто указателю в возможном направлении.


person Jesse Beder    schedule 25.10.2009    source источник
comment
Пожалуйста!!! ПРОЧИТАЙТЕ HOWTO выпуска программного обеспечения (en.tldp.org/HOWTO/ Software-Release-Practice-HOWTO/index.html) — вы всегда распаковываете вещи в подкаталог (yaml-cpp-0.2.3) и не разбрасываете свой код по текущему каталогу... Черт! (Хорошо: я должен знать лучше, но и вы должны знать!)   -  person Jonathan Leffler    schedule 25.10.2009
comment
Извините, вы правы. Я просто настолько привык к тому, что другие облажались таким образом, что я все равно всегда создаю новый каталог при распаковке. Но да, извините за это, я исправлю это в следующий раз. Спасибо и за ссылку.   -  person Jesse Beder    schedule 25.10.2009
comment
@Jesse: не соглашайся, чтобы другие так облажались. Потерпите это один раз; указать им на ошибку их пути, а затем отказаться иметь что-либо еще с программным обеспечением, которое не решит проблему.   -  person Jonathan Leffler    schedule 25.10.2009


Ответы (5)


Baffe Boyois дал правильный общий ответ - ваши правила CMake должны делать слишком много.

В MacOS X 10.5.8 (Leopard) я получаю:

Osiris JL: cmake ..
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jleffler/tmp/yaml-cpp-0.2.3/build
Osiris JL: make
Scanning dependencies of target yaml-cpp
[  2%] Building CXX object CMakeFiles/yaml-cpp.dir/src/._conversion.cpp.o
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1:1: warning: null character(s) ignored
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1: error: stray ‘\5’ in program
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1: error: stray ‘\22’ in program
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1: error: stray ‘\7’ in program
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1:5: warning: null character(s) ignored
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1: error: stray ‘\2’ in program
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1:7: warning: null character(s) ignored
/tmp/yaml-cpp-0.2.3/src/._conversion.cpp:1:17: warning: null character(s) ignored
...

Вы должны перечислить файлы, которые вам нужно скомпилировать; не надо просто компилировать все подряд.

Проблема, похоже, в CMakeLists.txt:

file(GLOB public_headers include/*.h)
file(GLOB private_headers src/*.h)
file(GLOB sources src/*.cpp)

Либо CMake GLOB вызывает слишком много энтузиазма (я использую версию 2.6-patch 4), либо вы не можете позволить себе его использовать, пока кто-то из ваших клиентов использует MacOS X.

То, что делает GLOB, расширяется, чтобы включить файлы, начинающиеся с '.' можно только догадываться; Я был бы склонен рассматривать это как ошибку в cmake.

Однако в качестве обходного пути я отредактировал CMakeLists.txt и заставил это работать:

file(GLOB public_headers include/[a-z]*.h)
file(GLOB private_headers src/[a-z]*.h)
file(GLOB sources src/[a-z]*.cpp)

Это не полное решение: я столкнулся с продолжением проблемы с кодом в каталоге yaml-reader. Я изменил файл yaml-reader/CMakeLists.txt практически таким же образом.

ВНЕШНЯЯ ПОМОЩЬ:

$ file ._*
._conversion.cpp: AppleDouble encoded Macintosh file
._exp.cpp:        AppleDouble encoded Macintosh file
._map.cpp:        AppleDouble encoded Macintosh file
._map.h:          AppleDouble encoded Macintosh file
._node.cpp:       AppleDouble encoded Macintosh file
._null.cpp:       AppleDouble encoded Macintosh file
._ostream.cpp:    AppleDouble encoded Macintosh file
._parser.cpp:     AppleDouble encoded Macintosh file
._regex.cpp:      AppleDouble encoded Macintosh file
._regeximpl.h:    AppleDouble encoded Macintosh file
._scanner.cpp:    AppleDouble encoded Macintosh file
._scanner.h:      AppleDouble encoded Macintosh file
._scanscalar.cpp: AppleDouble encoded Macintosh file
._scanscalar.h:   AppleDouble encoded Macintosh file
._sequence.cpp:   AppleDouble encoded Macintosh file
._simplekey.cpp:  AppleDouble encoded Macintosh file
._stream.cpp:     AppleDouble encoded Macintosh file
._token.h:        AppleDouble encoded Macintosh file
$ odx ._con*.cpp 
0x0000: 00 05 16 07 00 02 00 00 4D 61 63 20 4F 53 20 58   ........Mac OS X
0x0010: 20 20 20 20 20 20 20 20 00 02 00 00 00 09 00 00           ........
0x0020: 00 32 00 00 00 79 00 00 00 02 00 00 00 AB 00 00   .2...y..........
0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
*
0x0050: 00 00 00 00 41 54 54 52 00 3C E0 2B 00 00 00 AB   ....ATTR.<.+....
0x0060: 00 00 00 9C 00 00 00 0F 00 00 00 00 00 00 00 00   ................
0x0070: 00 00 00 00 00 00 00 01 00 00 00 9C 00 00 00 0F   ................
0x0080: 00 00 17 63 6F 6D 2E 61 70 70 6C 65 2E 54 65 78   ...com.apple.Tex
0x0090: 74 45 6E 63 6F 64 69 6E 67 00 00 00 55 54 46 2D   tEncoding...UTF-
0x00A0: 38 3B 31 33 34 32 31 37 39 38 34                  8;134217984
0x00AB:
$

Одна странная деталь - некоторые файлы в каталоге 'src' не имеют теневых файлов. Когда я делаю «tar -tvf yaml-cpp-0.2.3.tar.gz», я вижу, что файлы отправляются с исходным кодом:

Osiris JL: tar -tvf yaml-cpp-0.2.3.tar.gz
drwxr-xr-x beder/staff       0 2009-10-22 15:13:52 ./
-rw-r--r-- beder/staff    1750 2009-10-22 15:09:05 ./CMakeLists.txt
drwxr-xr-x beder/staff       0 2009-10-19 16:40:15 ./include/
-rw-r--r-- beder/staff     171 2009-09-06 13:41:54 ./include/._conversion.h
-rw-r--r-- beder/staff    1118 2009-09-06 13:41:54 ./include/conversion.h
-rw-r--r-- beder/staff     302 2009-07-29 15:25:23 ./include/crt.h
-rw-r--r-- beder/staff    2254 2009-10-19 16:40:14 ./include/emitter.h
-rw-r--r-- beder/staff    1660 2009-10-19 16:40:14 ./include/emittermanip.h
-rw-r--r-- beder/staff     171 2009-08-18 22:07:22 ./include/._exceptions.h
-rw-r--r-- beder/staff    5638 2009-08-18 22:07:22 ./include/exceptions.h
-rw-r--r-- beder/staff     765 2009-07-29 15:25:23 ./include/iterator.h
-rw-r--r-- beder/staff     444 2009-07-29 15:25:23 ./include/mark.h
-rw-r--r-- beder/staff     171 2009-09-06 12:25:12 ./include/._node.h
-rw-r--r-- beder/staff    3467 2009-09-06 12:25:12 ./include/node.h
-rw-r--r-- beder/staff     171 2009-09-15 20:54:20 ./include/._nodeimpl.h
...
-rw-r--r-- beder/staff     171 2009-07-29 21:28:26 ./include/._yaml.h
-rw-r--r-- beder/staff     321 2009-07-29 21:28:26 ./include/yaml.h
-rw-r--r-- beder/staff     167 2009-09-05 16:01:06 ./._install.txt
-rw-r--r-- beder/staff     652 2009-09-05 16:01:06 ./install.txt
-rw-r--r-- beder/staff    1073 2009-05-29 19:31:21 ./license.txt
drwxr-xr-x beder/staff       0 2009-10-22 14:49:11 ./src/
-rw-r--r-- beder/staff    1697 2009-08-24 16:28:46 ./src/aliascontent.cpp
-rw-r--r-- beder/staff    1171 2009-08-24 16:28:46 ./src/aliascontent.h
-rw-r--r-- beder/staff     112 2009-05-29 19:31:21 ./src/content.cpp
-rw-r--r-- beder/staff    1557 2009-08-24 16:28:46 ./src/content.h
-rw-r--r-- beder/staff     171 2009-09-06 13:31:56 ./src/._conversion.cpp
-rw-r--r-- beder/staff    2027 2009-09-06 13:31:56 ./src/conversion.cpp
...

Таким образом, вредоносные файлы поставляются с tar-файлом продукта. Вы где-то заразились - не знаю как.

person Jonathan Leffler    schedule 25.10.2009
comment
@bdonlan: да, это сработает, но сколько исходных файлов не начинаются с буквенного символа? Конечно, ваша нотация будет более компактной, если какие-либо файлы также начинаются с верхнего регистра. Я все еще думаю, что есть место, чтобы утверждать, что в cmake есть ошибка - подстановка оболочки не расширяется, чтобы соответствовать именам, начинающимся с точки, и cmake тоже не должен. - person Jonathan Leffler; 25.10.2009
comment
Хорошо поймал. Что мне кажется странным, так это то, что предыдущая версия скомпилировалась для них нормально. Что находится в ._whatever.cpp сгенерированных файлах? - person Jesse Beder; 25.10.2009
comment
Запуск: 'rm -f /._' в каталоге верхнего уровня, в который извлечено программное обеспечение, позволяет сборке работать с немодифицированными файлами cmake. - person Jonathan Leffler; 25.10.2009
comment
Оказывается, эти дополнительные скрытые файлы автоматически генерируются командой tar и не фактически существуют в моей системе. Они являются результатом расширенных атрибутов OS X; Мне удалось от них избавиться, и в новый tar-архив был включен только настоящий исходный код. Спасибо за вашу помощь! - person Jesse Beder; 25.10.2009
comment
Ну, я не уверен, как вы добавили расширенные атрибуты. Мое тестирование FWIW проводилось на MacOS X 10.5.8 (Leopard). С различными попытками мне не удалось увидеть эти файлы '._*', сгенерированные на моем диске, и при этом они не были созданы GNU tar (1.15.1) из /usr/bin или /usr/local/bin (да , однажды я разберусь, почему у меня есть оба). Итак, вы, вероятно, правы, что что-то подталкивает MacOS X к их созданию, а затем tar правильно их архивирует; Я просто не уверен, что вред наносит смола. Но у меня нет хорошего объяснения тому, что наносит ущерб. Используете ли вы какой-либо графический интерфейс (возможно, Xcode)? - person Jonathan Leffler; 26.10.2009
comment
Да, похоже, что если вы сохраните файл в Xcode (или в TextEdit, или, возможно, во что-нибудь с графическим интерфейсом), он добавит эти сумасшедшие расширенные атрибуты. Я потратил некоторое время на выяснение того, как с ними бороться — см. on-os-x" title="почему я получаю такие файлы, как foo, в своем архиве на os x">superuser.com/questions/61185/ для получения дополнительной информации - person Jesse Beder; 27.10.2009

Ошибки в ._regex.cpp, а не regex.cpp. Файлы, начинающиеся с ._, автоматически генерируются MacOS. Кажется, ваша система сборки пытается скомпилировать все файлы, заканчивающиеся на .cpp. Вероятно, он не должен компилировать что-либо, начинающееся с точки.

person Baffe Boyois    schedule 25.10.2009
comment
Эти файлы .+ создаются OSX в файловой системе, отличной от HFS+ (собственный формат Mac OS). - person mmmmmm; 25.10.2009

Может быть поврежденный файл с их стороны.

Что находится в строке 1 файла _regex.cpp в ИХ системе.

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

person Glen    schedule 25.10.2009

Убедитесь, что в каталоге сборки есть только файлы .o. У меня была эта проблема, и причиной была ошибка в моем Makefile (на самом деле это был файл scons), который создавал один исходный файл в файле .c вместо файла .o. Полученный файл был двоичным, но я предполагаю, что gcc пытался интерпретировать его как файл .c.

person Ben Gartner    schedule 15.01.2010

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

return (randomNumber % (tableSize - 2)) + 1;

Я через него был оператором по модулю, но оказалось, что кодировка что ли, но я решил это, удалив его и набрав вручную.

person BostonGeorge    schedule 22.03.2014