неявное объявление функции 'write' (включая unistd)

Я написал функцию, которая выводит текст на стандартный вывод. При компиляции (с использованиемgcc exemple.c ), я получаюwarning : implicit declaration of function 'write' . Вот пример:

example.c :

#include <unistd.h>

int main(void){
    write(1, "Hello World !", 13);

    return (0);
}

Выход :

exemple.c: In function ‘main’:
exemple.c:4:2: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration]
  write(1, "Hello World !", 13);

Я включилunistd.h заголовок , поэтому я не понимаю причину предупреждения.

Мне удалось "исправить" предупреждение, добавив

#include <sys/types.h>
//The real prototype, from unistd.h
extern ssize_t write(int __fd, void *__buf, size_t __n)__wur;

Но это говорит мне, что это может быть плохая идея.

Не следуетunistd.h как в этих примерах? Или есть лучший способ использовать / скомпилироватьwrite ?

Примечание : я компилирую с помощью gcc 5.3.1

Изменить : вот ссылка на.i файл, созданный при запускеgcc exemple.c -save-temps : instance.i

# prototype posix gcc-warning
Источник
  • 3
    Попробуйте запустить gcc -E exemple.c и посмотрите пути, напечатанные там. Вполне вероятно, что подобрался какой-то другой unistd.h , и не тот.
  • 1
    Ваша тестовая программа компилируется для меня без жалоб на очень похожем компьютере, и я знаю из обширного опыта работы с POSIX, что она должна компилироваться без жалоб. Наиболее вероятное объяснение заключается в том, что у вас не работает установка библиотеки C. Пожалуйста, запустите вашу компиляцию еще раз, используя ту же самую командную строку компилятора, но добавив в -save-temps ; это создаст файл с именем exemple.i . Загрузите этот файл туда, где мы его увидим, и измените URL-адрес вашего вопроса. (Публикация напрямую займет слишком много времени.)
  • 1
    Использование -std=c11 подавляет объявления нестандартных функций. Используйте -std=gnu11 или запросите расширения POSIX и X / Open с #define __XOPEN_SOURCE 700 или эквивалентным, прежде чем включать какие-либо системные заголовки.
  • 0
    @ Флориан Веймер - действительно, использованный путь не тот, который я ожидал
  • 0
    @JonathanLeffler Я подумал, что это тоже может быть проблемой, но даже в режиме -std=c89 без выбора функций #define s, glibc дает любому, кто включает unistd.h по крайней мере то, что было в этом заголовке в POSIX.1-1990 ( который включает write ).
  • 0
    @zwol - я загрузил файл
  • 2
    @Hollyol ОК, значит, у вас есть файл с именем /usr/local/include/unistd.h , и компилятор выбирает этот файл вместо правильного /usr/include/unistd.h . Теперь вопрос в том, почему у вас есть этот файл и что еще может быть в /usr/local/include что может мешать работе библиотеки C. (Предполагается, что этот каталог предназначен для заголовков сторонних библиотек, а не для заголовков, которые маскируют настоящую библиотеку C.) Пожалуйста, покажите нам результат ls -l /usr/local/include .
  • 0
    @zwol - в /usr/local/include больше ничего нет, только unistd.h
  • 1
    /usr/local/include не должно даже быть в пути включения по умолчанию, если вы не используете настраиваемую сборку gcc с префиксом /usr/local ... возможно, вы могли бы дать здесь некоторую предысторию (например, вы действительно создали gcc себя)
  • 0
    @MM - Нет, я не помню, чтобы что-то менял с помощью gcc, да и сам я его не создавал: /
  • 0
    @Hollyol Я все еще хочу увидеть вывод ls -l /usr/local/include , без редактирования . Собственно, сделайте это ls -la /usr/local /usr/local/include .
  • 2
    @MM Au contraire, /usr/local/include всегда находится в пути включения gcc по умолчанию, потому что даже если префикс $ - это что-то еще, вы, вероятно, захотите подобрать локально установленные сторонние библиотеки. (Это дизайнерское решение было принято в 1990-х, может быть, даже в 1980-х, и я видел аргумент, что сейчас это неверно.)
  • 0
    «Я использую Linux 4.4.16-21-generic x86-64» - это версия вашего ядра, и она вряд ли актуальна. Есть ли какие-либо комментарии в верхней части вашего /usr/local/include/unistd.h ?
  • 0
    @zwol - Вот он: total 4 -rw-r--r-- 1 root root 157 Aug 19 2016 unistd.h
  • 0
    @KeithThompson - В нем говорится, что Includes machine specific syscall numbers , на самом деле, единственное, что он делает, это включает <asm/unistd.h>
  • 0
    Я исправил проблему, установив переменную окружения: C_INCLUDE_PATH=/usr/include , чтобы этот каталог просматривался до usr/local/include , как предлагается здесь - network-theory.co.uk/docs/gccintro/gccintro_23.html
  • 0
    @Hollyol Итак, я думаю, что у вас тут кто-то скопировал linux/unistd.h в /usr/local/include . Я не имею ни малейшего представления, зачем кому-то это делать, и, как вы видели, это мешает компиляции обычных программ. Это ваш персональный компьютер или им управляет кто-то другой? У кого-нибудь еще есть к нему доступ? Вы помните, что делали 19 августа 2016 года? Вы помните, как когда-либо возились с файлами заголовков?
  • 0
    @zwol - это мой персональный компьютер, и я не помню, чтобы играл с заголовками, но, возможно, я все равно это сделал.
  • 0
    @Hollyol Ну, я думаю, вы, вероятно, можете просто удалить unistd.h в /usr/local/include , но если вы когда-нибудь узнаете, как он туда попал и почему, я хотел бы знать.
  • 0
    В системе на основе dpkg вы можете попробовать dpkg -S /usr/local/include/unistd.h чтобы попытаться определить, установлен ли этот файл пакетом.
  • 0
    @zwol - Удаление файла устраняет предупреждение, спасибо!
Codelisting
за 0 против

я имел<unistd.h> включен, но я все равно получил предупреждение. Мне удалось избавиться от предупреждения, добавив#define _GNU_SOURCE в заголовок, так что теперь это:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

У меня была аналогичная проблема при использованииbrk() а такжеsbrk() когда я скомпилировал:

gcc -std=c99
  • 1
    Компиляция с -std=gnu99 также должна позаботиться об этом.
Codelisting
Популярные категории
На заметку программисту