【问题标题】:Constants not loaded by compiler编译器未加载的常量
【发布时间】:2012-02-11 11:44:15
【问题描述】:

我开始研究 POSIX 计时器,所以我也开始做一些练习,但我立即遇到了编译器的一些问题。 编译此代码时,我收到一些关于 CLOCK_MONOTONIC 等宏的奇怪消息。这些是在 time.h 等各种库中定义的,但编译器会给我错误,就好像它们没有定义一样。

这很奇怪,因为我使用的是 Fedora 16,而我的一些使用 Ubuntu 的朋友得到的编译器错误比我少:-O

我正在用gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -lrt编译

这是我得到的错误:

  • struct sigevent sigeventStruct

    storage size of ‘sigeventStruct’ isn’t known
    unused variable ‘sigeventStruct’ [-Wunused-variable]
    Type 'sigevent' could not be resolved
    unknown type name ‘sigevent’
    
  • sigeventStruct.sigev_notify = SIGEV_SIGNAL

    ‘SIGEV_SIGNAL’ undeclared (first use in this function)
    request for member ‘sigev_notify’ in something not a structure or union
    Field 'sigev_notify' could not be resolved
    
  • if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1)

    implicit declaration of function ‘timer_create’ [-Wimplicit-function- declaration]
    ‘CLOCK_MONOTONIC’ undeclared (first use in this function)
    Symbol 'CLOCK_MONOTONIC' could not be resolved
    

代码如下:

#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>

int main()
{
        timer_t numero1;
        struct sigevent sigeventStruct;
        sigeventStruct.sigev_notify = SIGEV_SIGNAL;
        if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1)
        {
                printf( "Errore: %s\n", strerror( errno ) );
        }
        return 0;
}

【问题讨论】:

  • 只是一个建议,不要以点形式出现错误,只需将它们完全复制到问题中的 &lt;pre&gt;&lt;/pre&gt; 块中即可。
  • 好的,下次我会考虑你的建议

标签: c posix time.h


【解决方案1】:

首先,如果您希望标识符SIGEV_SIGNALsigeventStructCLOCK_MONOTONIC 可用,您可以使用-std=gnu99 而不是-std=c99 编译您的代码。

正如@adwoodland 所述,这些标识符在_POSIX_C_SOURCE 设置为>= 199309L 时声明,-std=gnu99 就是这种情况。您也可以使用-D_POSIX_C_SOURCE=199309L -std=c99 或在源代码中定义宏。

其次,查看timer_create 原型,您必须将指针作为第二个和第三个参数传递给函数:

timer_create(CLOCK_MONOTONIC, &sigeventStruct, &numero1)
                              ^                ^

您还必须为strerror 函数声明包含标准标头string.h

【讨论】:

  • 很好地抓住了timer_t 也是一个指针。我错过了,因为-Wall -Wextra 甚至没有警告它!
  • 如果我用 -std=gnu99 编译我有点困惑,我仍然需要 #define _POSIX_C_SOURCE 199309L 来写在代码清单中吗?当使用 -std=c99 时,使用 -D_POSIX_C_SOURCE=199309L -std=c99 或 -std=c99 和 #define _POSIX_C_SOURCE 199309L 是一样的吗?
  • @Caterpillar 如果您使用-std=gnu99,则您无事可做,_POSIX_C_SOURCE 将被自动定义,其值为 > 199309L。对于-std=c99,使用-D#define 解决方案是等效的。使用#define 时,请务必将#define 放在time.hsignal.h 包含之前的一行中
  • 我解决了很多问题,但仍然无法解决 CLOCK_MONOTONIC。我正在使用 -std=gnu99
【解决方案2】:

如果您使用的是-std=c99,您需要告诉 gcc 您仍在使用最新版本的 POSIX:

#define _POSIX_C_SOURCE 199309L

之前任何#include,甚至在命令行上使用-D

其他错误:

  • 缺少#include &lt;string.h&gt;
  • 您需要一个指向timer_create 的指针,即&amp;sigeventStruct 而不仅仅是sigeventStruct

【讨论】:

    【解决方案3】:

    其他答案建议 _POSIX_C_SOURCE 作为启用宏。这当然有效,但它不一定支持单一 Unix 规范 (SUS) 中的所有内容。为此,您应该设置_XOPEN_SOURCE,它也会自动设置_POSIX_C_SOURCE。我有一个我称之为"posixver.h" 的标题,其中包含:

    /*
    ** Include this file before including system headers.  By default, with
    ** C99 support from the compiler, it requests POSIX 2001 support.  With
    ** C89 support only, it requests POSIX 1997 support.  Override the
    ** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
    */
    
    /* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
    /* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
    /* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
    
    #if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
    #if __STDC_VERSION__ >= 199901L
    #define _XOPEN_SOURCE 600   /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
    #else
    #define _XOPEN_SOURCE 500   /* SUS v2, POSIX 1003.1 1997 */
    #endif /* __STDC_VERSION__ */
    #endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
    

    它针对我所使用的系统进行了调整,这些系统不能全部识别 700 值。如果您正在使用相对现代的 Linux,我相信您可以使用 700。它位于标头中,因此当我想更改规则时只需更改一个文件。

    【讨论】:

    • 谢谢,我保留这个库以备将来使用
    【解决方案4】:

    参考 CLOCK_MONOTONIC 未定义问题:

    正如 Caterpillar 指出的,这是一个 eclipse 错误,更准确地说是 CDT-Indexer 错误,解决方法是 eclipse bugs, comment 12

    【讨论】:

    • 您应该添加解决方法,以防链接失效
    【解决方案5】:

    我用 -std=gnu99 解决了很多问题(没有指定任何 POSIX 版本),但我仍然有

    CLOCK_MONOTONIC 无法解析

    在互联网上搜索时,我发现了一些 Eclipse 错误报告,有人抱怨此问题。必须更好地检查是否是 Eclipse 错误,因为

    gcc -Wall -w -o Blala timer.c -std=gnu99 -lrt

    它编译

    【讨论】:

    • 是的,这是 Eclipse 的 CDT 插件的错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2019-07-08
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多