weixin_39787594
2020-11-30 01:01 阅读 15

lex.yy.c: error: implicit declaration of function 'strdup'

Commit a17d79e9 breaks code that requires functionality from POSIX standards more recent than 1990, in this case strdup:

https://buildd.debian.org/status/fetch.php?pkg=libreswan&arch=arm64&ver=3.23-2&stamp=1518540444&raw=0


parser.l: In function 'parser_y_init':
parser.l:104:33: error: implicit declaration of function 'strdup' [-Werror=implicit-function-declaration]
  ic_private.stack[0].filename = strdup(name);
                                 ^~~~~~

With gcc in non-strict mode (which is the default, and the libreswan build above even explicitely sets -std=gnu99) _POSIX_C_SOURCE defaults to 200809. Commit a17d79e9 defines _POSIX_C_SOURCE to 1, and this commit was already backported into flex in Debian unstable. strdup requires _POSIX_C_SOURCE >= 200809.

I do not think flex should mess with feature test macros in the files it generates.

该提问来源于开源项目:westes/flex

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

13条回答 默认 最新

  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    You should #define _POSIX_C_SOURCE to an appropriate value in your user code. I suggest you fix it in the libreswan package downstream.

    You can add something like

    
    %top{
    #define _POSIX_C_SOURCE 200809L
    }
    

    I think this is due to our lack of documentation, I apologize if this is the case. (Can you suggest a documentation fix?)

    点赞 评论 复制链接分享
  • weixin_39787594 weixin_39787594 2020-11-30 01:01

    Yes, libreswan and other packages that got broken due to your change could workaround this regression by starting to also mess around with feature test macros. This doesn't mean that it is correct that flex suddenly started to overwrite the compiler setting in generated files.

    Note that the packages that fail to build are only the tip of the iceberg: Without the -Werror your change would have resulted in libreswan being miscompiled, and there are likely packages that are getting miscompiled due to that for obvious reasons.

    flex has been using fileno without messing with feature test macros for > 20 years, and this is also documented.

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    I think I found the problem... it's my fault, definitely, when I miss the glibc .

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    Would you please test the patch in #315? BTW, I think libreswan and other packages (and flex also) should definitely consider adding the flag -Werror=implicit-function-declaration even on release builds.

    点赞 评论 复制链接分享
  • weixin_39787594 weixin_39787594 2020-11-30 01:01

    315 looks clearly bogus.

    Quoting feature_test_macros(7):

    In order to be effective, a feature test macro must be defined before including any header files.

    Please stop messing with stuff you do not fully understand, and where the old code has been working for decades.

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    The reason for the feature test macros to be added in skeleton is to allow the generated scanner to build in strict-ANSI mode. The "old code working for decades" you mentioned are GNU extensions, which I broke it accidentally. I'm not sure why are you claiming that I "do not fully understand" stuff. (That's why I write lengthy explanation in this commit message!) Are you suggesting a better change, or what are you wishing for?

    点赞 评论 复制链接分享
  • weixin_39787594 weixin_39787594 2020-11-30 01:01

    It is not correct when you are saying I would be talking about GNU extensions, the strdup from the libreswan build failure is part of POSIX.1-2001.

    The flex FAQ says:

    https://github.com/westes/flex/blob/master/doc/flex.texi#L5541-L5550

    Why do flex scanners call fileno if it is not ANSI compatible?

    Flex scanners call 'fileno()' in order to get the file descriptor corresponding to 'yyin'. The file descriptor may be passed to 'isatty()' or 'read()', depending upon which '%options' you specified. If your system does not have 'fileno()' support, to get rid of the 'read()' call, do not specify '%option read'. To get rid of the 'isatty()' call, you must specify one of '%option always-interactive' or '%option never-interactive'.

    It is rare that people are compiling in strict-ANSI mode. The people who do usually know what they are doing, and when they are using strict-ANSI mode they want such potential portability problems flagged by compile warnings/errors - that's the reason for using strict-ANSI mode.

    The best change would be a revert of commit a17d79e.

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    It is not correct when you are saying I would be talking about GNU extensions, the strdup from the libreswan build failure is part of POSIX.1-2001.

    The reality is that libipsecconf from libreswan was expecting strdup being available without explicitly defining _POSIX_C_SOURCE, and according to the build log you provided, no, gcc did not define _POSIX_C_SOURCE to 200809L as you expected. The reason strdup worked there is due to _BSD_SOURCE or, in glibc >= 2.20, _DEFAULT_SOURCE.

    Feel free to prove me wrong by providing a dump of gcc's preprocessor defines of lib/libipsecconf/lex.yy.c.

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    Correction: It's glibc >= 2.20 that defines _POSIX_C_SOURCE to 200809L due to the _DEFAULT_SOURCE rule. GCC didn't define any of this.

    点赞 评论 复制链接分享
  • weixin_39787594 weixin_39787594 2020-11-30 01:01

    This has nothing to do with where in the whole gcc/glibc machinery these macros get defined.

    The reality is that you were wrong when you were claiming strdup would be a GNU extension, since it is actually a standard POSIX function like fileno.

    As I already explained there was no actual problem that got fixed by commit a17d79e, and both commit a17d79e and #315 are introducing new bugs. Everything was working and properly documented, and I have yet to see any suggested way forward that would be better than just reverting commit a17d79e.

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    The system libraries had no obligation to reveal POSIX library routines. It's just that many systems do this by default out of convenience. The feature test macros are there to control whether POSIX library functions should be visible or not, and, quote from POSIX.1-2004:

    A POSIX-conforming application should ensure that the feature test macro _POSIX_C_SOURCE is defined before inclusion of any header.

    The flex generated scanner is, in some sense, an application, and therefore is (partly) responsible for ensuring feature test macros are defined. If libreswan did that properly (instead of relying on implicit _DEFAULT_SOURCE), then there won't be the bug. BTW, I didn't claim strdup be a GNU extension, I was saying that the language and compilation mode was a GNU extension mode.

    What #315 was fixing is the failure of checking feature test macros and the fallback define of _POSIX_C_SOURCE accidentally inhibiting the _DEFAULT_SOURCE being defined. Personally I won't go for the revert-all approach (unless you are to readdress #263), but the decision won't be mine to make.

    点赞 评论 复制链接分享
  • weixin_39787594 weixin_39787594 2020-11-30 01:01

    Your quote from POSIX reaffirms that #315 is wrong.

    I already said above that #263 doesn't need any fixing at all since it is established and documented behaviour in flex, and people who use strict-ANSI mode do that actually for getting these warnings/errors you were attempting to fix.

    点赞 评论 复制链接分享
  • weixin_39644146 weixin_39644146 2020-11-30 01:01

    It was documented to be ANSI-incompatible, but not documented to break in ANSI compilers. I could have a lot of reasons to compile in -std=c99 mode, and reasons to expect it won't fail in front of me even when fileno() is used. That was why I filed #263.

    点赞 评论 复制链接分享

相关推荐