Skip to content

libc++ char_traits.h assumes EOF is always available #85158

Description

@petrhosek

libc++ assumes that EOF is always available and uses it unconditionally in the char_traits.h implementation.

In file included from /llvm_libcxx/include/chrono:830:                                                                                                                                                                                                                                                                                                                                 
In file included from /llvm_libcxx/include/__chrono/convert_to_tm.h:22:                                                                                                                                                                                                                                                                                                                
In file included from /llvm_libcxx/include/__chrono/statically_widen.h:17:                                                                                                                                                                                                                                                                                                             
In file included from /llvm_libcxx/include/__format/concepts.h:17:                                                                                                                                                                                                                                                                                                                     
In file included from /llvm_libcxx/include/__format/format_parse_context.h:16:                                                                                                                                                                                                                                                                                                         
In file included from /llvm_libcxx/include/string_view:225:                                                                                                                                                                                                                                                                                                                            
/llvm_libcxx/include/__string/char_traits.h:169:100: error: use of undeclared identifier 'EOF'                                                                                                                                                                                                                                                                                         
  169 |   static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); }                                                                                                                                                                                                                                                                                                                        
      |                                                                                                    ^                                                                                                                                                                                                                                                                                                                              
/llvm_libcxx/include/__string/char_traits.h:169:66: error: no return statement in constexpr function                                                                                                                                                                                                                                                                                   
  169 |   static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); }

LLVM libc doesn't currently define EOF on baremetal targets because there's no filesystem support (since baremetal targets typically don't have filesystem to begin with) which results in a compiler error.

We could extend LLVM libc to define EOF even on baremetal targets, but it's an open question whether libc++ should be able to handle the case where EOF is undefined.

This is related to issue #84879.

Activity

  1. added
    libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
    embeddedSupport for embedded development
    on Mar 14, 2024
  2. philnik777 commented on Mar 14, 2024

    @philnik777
    Contributor

    I can't really think of a good reason a libc shouldn't provide it. Given that the main thing this might lead to are ODR violations, since libc++ would have to provide it's own if it can't find the libc's, IMO the libc should just provide it. It's not much harder than adding #define EOF (-1) to a header.

  3. added
    wontfixIssue is real, but we can't or won't fix it. Not invalid
    on Mar 15, 2024
  4. ldionne commented on Mar 27, 2024

    @ldionne
    Member

    I've come across this issue in a different setting and I had the same conclusion -- libc should provide it.

    Basically, EOF is just a really unfortunately-named macro, but it is technically not tied specifically to input and output. It's literally just a macro defined to some integer, and that should be defined even when the underlying system has no notion of I/O or files. It feels really weird to have a header named <stdio.h> in a freestanding C library and to provide a macro named EOF but not any other IO related functionality, but I think that's the right thing to do.

  5. frederick-vs-ja commented on Apr 3, 2024

    @frederick-vs-ja
    Contributor

    I suspect that there should be an LWG issue - currently std::char_traits<char>::eof is required to be freestanding due to P2338R4, but it's also required to return the value of EOF which is not yet freestanding.

  6. jwakely commented on Apr 8, 2024

    @jwakely
    Contributor

    The eof, not_eof, to_int_type and to_char_type members of char_traits are only needed by iostreams, so I see no reason for them to be present in freestanding.

    In libstdc++ we make eof and not_eof depend on hosted, so they're absent for freestanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    embeddedSupport for embedded developmentlibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.wontfixIssue is real, but we can't or won't fix it. Not invalid

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions