2014-12-29 5 views
3

Я ранее написал код C++, который #include s заголовки Unix и Linux API, и эти программы вызывают ожидаемое поведение. Тем не менее, я не знаю, на что можно положиться. Вполне возможно, что несовместимость между C и C++ может привести к тому, что допустимые заголовки C будут действовать неожиданными способами при использовании программами на C++.Являются ли заголовки API Unix и Linux совместимыми с C++?

Могут ли заголовки Unix и Linux API надежно использоваться кодом, который будет скомпилирован как C++?

Является ли это целью авторов этих заголовков? Или эти заголовки предназначены только для того, чтобы быть действительными?

Есть ли какие-либо известные подводные камни при этом?

Очевидно, что дистрибутивы Unix и Linux многочисленны, и я не ожидаю ответа на каждый дистрибутив по одному. Мое ожидание состоит в том, что тот же ответ будет применяться практически ко всем дистрибутивам Unix и Linux, и исключения подтвердят это правило. Если это предположение неверно, объяснение этого также будет правильным ответом.

По заголовкам Unix Я имею в виду эти:

http://www.unix.org/version3/apis/headers.html

По заголовкам Linux я имею в виду заголовки, предоставляемые дистрибутивах Linux, как правило, в качестве пакета под названием «Linux-заголовки», которые позволяют программам взаимодействовать с ядром Linux , Например, это Debian пакет:

https://packages.debian.org/wheezy/kernel/linux-headers-3.2.0-4-amd64

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

Редактировать Я имею в виду только заголовки, используемые программами пользовательского пространства.

+3

что вы подразумеваете под UNIX и заголовки Линукс – redFIVE

+1

Ну, я оказался в ситуации, когда я должен был включать в себя C++ заголовки первого (например, ''), а затем включить специфичные для платформы заголовки (например, ''). Когда включения были почитаемы, компиляция потерпит неудачу. (Или, может быть, ситуация была наоборот). – jww

+0

@redFIVE отредактирован. Это то, что вы искали? Я думал, что «unix headers» было разумным описанием, чтобы я мог что-то не понимать. Было ли это «Unix и Linux» запутанным? – Praxeolitic

ответ

5

стандартные С заголовки, как <stdio.h>, <stdlib.h> и так далее указаны в Приложении D из C++, который устанавливает:

Эти устаревшие функции, где Устаревшие определяется как: Нормативная для текущей редакции стандарта, но не гарантируется быть частью Стандарта в будущих версиях.

Не-осуждается C++ версии стандартных заголовков C имеют имена, как <cstdio>, <cstdlib> и т.д., и они технически поставить свои определения в std (не глобального) пространства имен. Таким образом, чтобы быть 100% совместимым с не уходящим части спецификации C++, вы должны написать что-то вроде этого:

#include <cstdio> 

int main() { 
    std::printf("Hello, world!\n"); 
} 

Тем не менее, насколько мне известно, ни одна из существующих реализация на самом деле заставляет вас сделать это, и, на мой взгляд, это вряд ли когда-либо будет. Поэтому на практике вы можете спокойно использовать стандартные заголовки C на C++ без особого беспокойства.

Кроме того, если вы находитесь на (например,) системе POSIX, вы можете в целом использовать функциональность POSIX с C++ одинаково безопасно. Конечно, никто не намеренно нарушает это, потому что пользователи будут восставать.

Однако при смешивании парадигм возможен случайный поломка. Если и платформа, и языковой стандарт предоставляют некоторую функцию, вы должны использовать одну или другую, но не обе. В частности, я бы не смешивал механизмы потоковой передачи и синхронизации POSIX со стандартными механизмами потоковой синхронизации и синхронизации C++ 11, потому что легко представить, что оптимизатор слишком много знает о последнем и генерирует код, несовместимый с первым.

[Update, разработать несколько]

<unistd.h> является примером того, что я имею в виду, зависимый от платформы функциональности. Как правило, он отлично работает с C++, и ни библиотека, ни разработчики компилятора не будут беспорядочно разбивать его, потому что это будет слишком раздражать. Итак, продолжайте и звоните getpid() или pipe() или что угодно.

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

  • Вы можете позвонить по телефону new с помощью устройства обработки сигналов?
  • Можете ли вы использовать dup2 на дескриптор 0 для перенаправления cin?
  • Какие функции POSIX можно безопасно вызывать во время статической инициализации (т. Е. До выполнения main)?

Эти вопросы и другие подобные им не адресуются любые spec. Ответы зависят от вашей конкретной реализации и могут меняться между выпусками.

Сказав все это ... Почти всякая нетривиальная программа на C++ основана на специфических для платформы функциональных возможностях, открытых некоторым C-интерфейсом. Итак, то, что вы описываете, будет отлично работать на практике, если вы (а) имеете представление о том, что происходит «под капотом»; (b) имеют разумные ожидания; и (c) не пытайтесь смешивать стандартные и платформенные парадигмы.

+0

Стандартные заголовки библиотек C действительно включены в заголовки Open Group, требующие Unix, но заголовки, которые я имел в виду, это те, которые не упоминаются в стандарте C++, например. 'Unistd.h'. – Praxeolitic

+0

@Praxeolitic: 'unistd.h' является примером того, что я имел в виду в моих последних двух абзацах. См. Также обновление, которое я только что добавил. – Nemo

1

1) Да: «стандартные заголовки» - стандарт. Вы можете безопасно использовать их независимо от платформы.

2) Да: вы можете смешивать заголовки C (например, <stdio.h>) с заголовками C++ (например, <iostream>) в одной и той же переводческой единице C++.

3) NO: вы НЕ должны использовать ядра Linux заголовки в программе пользовательского режима, ни наоборот.

Заголовки ядра Linux предназначены для драйверов режима ядра, не для «обычных» приложений для пользовательского пространства.

Вот немного больше информации:

+1

Unix и Linux заголовки не являются стандартными в смысле стандарта C++. 'stdio.h' покрывается стандартом C++. Вы можете найти источник на 1)? Я думаю, что фраза, которую я должен был использовать, был «Linux API header». Это имеет смысл? – Praxeolitic

+0

Просто не объединяйте заголовки типа «kernel/linux-headers-3.2.0-4-amd64» с заголовками в/usr/include (например, «stdio.h»). Последнее предназначено для программ пользовательского пространства; первый для модулей ядра и т.п. Это было моим основным моментом ... – FoggyDay

Смежные вопросы