> Придумаешь тоже! Ни .с, ни .h не компилируются!!!С точностью до наоборот. Существующая возможность принудительно задавать тип файла через опцию "-x" не отменяет того факта, что и .c, и .h компилируются. По умолчанию компилятор определяет тип файла как раз таки по расширению). Из "man gcc":
-x none
Turn off any specification of a language, so that subsequent files are handled according to their file name suffixes (as they are if -x has not been used at all).
Да, и раз уж на то пошло, то даже .h можно компилировать, см. Precompiled headers: https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
А .c можно не компилировать напрямую, а например инклудить в другие .c файлы; см. например вывод следующей команды в каталоге с сырцами кернела:
grep -r 'include ".*\.c"' drivers/usb/*
Вот тут объяснено зачем это может понадобиться:
http://stackoverflow.com/questions/232693/including-one-c-so...
В конечном итоге всё сводится к пониманию простых вещей, описанных в стандарте и в "man gcc":
1. процесс сборки: препроцессинг (*.c, *.h -> *.c), компиляция (*.c -> *.S), ассемблирование (*.S -> *.o), компоновка (*.o -> бинарь)
2. для сборки программы необходимо и достаточно чтобы был один .c-файл с одной функцией с именем main(), которая будет являться точкой входа программы.
> $ echo 'int main(){ return 0;}' > system32.dll
> $ gcc -xc system32.dll
> $ ./a.out
Ты прямо указываешь компилятору, что "трактуй этот файл как .c", т.е. ты свой файл обозвал .c, только неявно.
По умолчанию gcc определяет тип файла по его расширению, а значит компилируются всё же .c файл.
> $ gcc -xc /dev/null -c
> $ objdump -d null.o
> objdump -d null.o
> null.o: формат файла elf64-x86-64
> Гы :)
Да, пустой файл можно скомпилировать (правда особого смысла в этом нет).