проблема приведения с функцией realpath (программирование на c)

Когда я компилирую следующий код:

#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>    

int
main(int argc, char *argv[])
{
    char *symlinkpath = argv[1];
    char actualpath [PATH_MAX];
    char *ptr;
    ptr = realpath(symlinkpath, actualpath);
    printf("%s\n", ptr);
}

Я получаю предупреждение в строке, содержащей вызов функции realpath:

warning: assignment makes pointer from integer without a cast

Кто-нибудь знает, что случилось? Я использую Ubuntu Linux 9.04.


person Ralph    schedule 18.10.2009    source источник


Ответы (2)


Это очень просто. Glibc рассматривает realpath() как расширение GNU, а не POSIX. Итак, добавьте эту строку:

#define _GNU_SOURCE

... до включения stdlib.h, чтобы он был прототипирован и, как известно, возвращал char *. В противном случае gcc будет считать, что он возвращает тип по умолчанию int. Прототип в stdlib.h не виден, если не определено _GNU_SOURCE.

Следующее выполняется нормально без предупреждений с -Wall:

#include <stdio.h>
#include <limits.h>

#define _GNU_SOURCE
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    char *symlinkpath = argv[1];
    char actualpath [PATH_MAX];
    char *ptr;
    ptr = realpath(symlinkpath, actualpath);
    printf("%s\n", ptr);

    return 0;
}

Вы увидите подобное поведение с другими популярными расширениями, такими как asprintf(). Стоит заглянуть в /usr/include/, чтобы точно увидеть, насколько этот макрос включается и что он изменяет.

person Tim Post♦    schedule 18.10.2009
comment
На самом деле вы должны прочитать man feature_test_macros. Кроме того, man-страницы для realpath, asprintf и т. д. сообщают, какие макросы должны присутствовать для их объявления. - person ephemient; 18.10.2009
comment
@ephemient: заголовки — это документация, когда дело доходит до изменения поведения стандартной библиотеки C. Назовите меня параноиком, но опечатки случаются в обновлениях документации от релиза к релизу. Иногда что-то не так, иногда изменения не заносятся в документацию... иногда новые изменения документируются некорректно. Я знаю, что изучение glibc, как известно, заставляет головы взрываться, но стоит взглянуть на заголовки. Вам нужно знать, что на самом деле делает каждый макрос, что лучше всего получить с помощью grep и других средств. - person Tim Post♦; 29.10.2009

Компилятор не знает, что такое realpath, поэтому предполагает, что это функция, возвращающая целое число. Он делает это по историческим причинам: многие старые программы на C полагались на это.

Вероятно, вам не хватает его объявления, например. забыв #include его заголовочный файл.

person Edmund    schedule 18.10.2009
comment
Да, поместите stdlib include вверху. - person aviraldg; 18.10.2009
comment
Нет, включение stdlib не избавляет от этого - person Ralph; 18.10.2009
comment
Я знаю, теперь все, что мне нужно сделать, это выяснить, что это такое :) Могу ли я предоставить какую-либо другую информацию, которая была бы полезна? - person Ralph; 18.10.2009
comment
в glibc realpath() является расширением. - person Tim Post♦; 29.10.2009