最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Using C std headers in c++ mode, how to specifiy C version - Stack Overflow

programmeradmin1浏览0评论
#include <stdio.h>
#include <stdckdint.h>
#include <stdint.h>
//#include <stdbool.h> // needed when compiled as c++ with -std=c++23

int main()
{
    int64_t value1 = 34;
    int32_t value2 = 177;
    uint8_t result;
    bool overflowed = ckd_add(&result, value1, value2);
    if (overflowed) {
        printf("result overflowed\n");
    } else {
        printf("result is %hhu\n", result);
    }
    return 0;
}

The above code compiles fine with GCC when compiled as C with -std=C23, but it does not compile as C++ with -std=c++23. See

The error is

<source>:13:23: error: '_Bool' was not declared in this scope
   13 |     bool overflowed = ckd_add(&result, value1, value2);

Seems ironic that you have to include <stdbool.h> in C++ but not in C :D.

-> Is it possible to specify C23 mode (or any other mode, in particular for GCC) when using C std libraries in C++?

(my assumption is this error arises because the C lib is not in C23 mode and thus does not have bool and _Bool)

Edit: My assumption was wrong. The C version is already C23 otherwise ckd_add should not be available. The original question is not answered yet, though.

#include <stdio.h>
#include <stdckdint.h>
#include <stdint.h>
//#include <stdbool.h> // needed when compiled as c++ with -std=c++23

int main()
{
    int64_t value1 = 34;
    int32_t value2 = 177;
    uint8_t result;
    bool overflowed = ckd_add(&result, value1, value2);
    if (overflowed) {
        printf("result overflowed\n");
    } else {
        printf("result is %hhu\n", result);
    }
    return 0;
}

The above code compiles fine with GCC when compiled as C with -std=C23, but it does not compile as C++ with -std=c++23. See https://godbolt./z/Tsf7MahPe

The error is

<source>:13:23: error: '_Bool' was not declared in this scope
   13 |     bool overflowed = ckd_add(&result, value1, value2);

Seems ironic that you have to include <stdbool.h> in C++ but not in C :D.

-> Is it possible to specify C23 mode (or any other mode, in particular for GCC) when using C std libraries in C++?

(my assumption is this error arises because the C lib is not in C23 mode and thus does not have bool and _Bool)

Edit: My assumption was wrong. The C version is already C23 otherwise ckd_add should not be available. The original question is not answered yet, though.

Share Improve this question edited Nov 19, 2024 at 15:05 user765269 asked Nov 19, 2024 at 14:17 user765269user765269 4221 gold badge5 silver badges14 bronze badges 4
  • 8 Build C code as C, build C++ code as C++. Don't mix and match the two different languages (and yes, C and C++ are two very different languages). – Some programmer dude Commented Nov 19, 2024 at 14:20
  • 1 "Seems ironic that you have to include <stdbool.h> in C++ but not in C :D." Simply include for both languages. Whit is the problem and is it "ironic"? (I do not see any irony) – 0___________ Commented Nov 19, 2024 at 14:28
  • 2 Each version of the C++ standard incorporates a specific version of the C standard by reference. It makes no provision for choosing which C version to use. A specific C++ implementation might choose to provide that as a feature (that deviates from the C++ standard), but generally, you must write your code to conform the the C++ standard and its paired C version, not make the version of C conform to your code. – Eric Postpischil Commented Nov 19, 2024 at 14:34
  • fyi C++ Draft Standard - [diff] "...Subclause [diff.iso] lists the differences between C++ and C, in addition to those listed above, by the chapters of this document...." – Richard Critten Commented Nov 19, 2024 at 14:56
Add a comment  | 

4 Answers 4

Reset to default 2

Each version of C++ refers to a specific version of C as normative reference.

For example C++23 refer to C17. So anything added later to C is not going to be part of C++23 either way (except if there happens to be convergent evolution such that the standards happen to specify the same feature independently of one another).

Even if C++23 refers to C17, that doesn't mean that all C17 features are supported in C++23. Instead, the C++ standard mentions explicitly what is and isn't incorporated into C++.

You can't expect to be able to use C standard library functions that are not incorporated into C++ in C++ code. There is no meaning in which you can mix and match C and C++ versions either.

So, you aren't guaranteed that <stdckdint.h> or the functions declared in it will work in C++ in any version or with any compiler configuration. If it is supported in some way, then that's the compiler being forthcoming and purely a compiler-specific extension. You can of course petition your compiler writers nicely if they could write the C library functions in such a way that they are also usable in C++ code. That's up to them.

It is really important to understand that these are two distinct languages that just have a certain common subset due to their origin. There are also some efforts to maintain or extend that common subset, but both languages otherwise develop independently from one another.

stdckdint.h is a C header, defined in the C23 standard. It was not meant to be used in a C++ program. In this case, it fails because it tries to use _Bool, which (as other answers and comments point out) does not exist in C++.

Headers from the C++ standard library can be recognized because they have no file extension, for example cstdint instead of stdint.h. Unfortunately there is no C++ equivalent of stdckdint.h (yet?).

In C++, the _Bool type from C is not defined by default because the language provides its own bool type as a built-in, native type. The C++ language design intentionally separates itself from some of C's legacy features. Here's why _Bool is not available by default in C++23

_Bool is retained in the C++ language as part of the C compatibility layer. If you include <stdbool.h> in a C++ program, it defines bool as an alias for _Bool, along with true and false.

On the contrary _Bool is a built-in type in C23, as it has been since C99. The C language explicitly defines _Bool as a fundamental type, used to represent Boolean values (true and false).

That is the reason why you have to include stdbool.h when compiling as C++

So if you want to use this header - you will have to accept it or write something more C++ish


template <typename T>
constexpr bool ckd_add(T a, T b, T& result)
{
    static_assert(std::is_integral_v<T>, "ckd_add only supports integral types");

    bool no_overflow = true;

    if ((b > 0) && (a > std::numeric_limits<T>::max() - b))
    {
        no_overflow = false;
    }
    else if ((b < 0) && (a < std::numeric_limits<T>::min() - b))
    {
        no_overflow = false;
    }
    else
    {
        result = a + b;
    }

    return no_overflow;
}

Others have already answered your question, I'll just say that you can use predefined macros to conditionally include <stdbool.h> like so:

#ifdef __cplusplus
  #include <stdbool.h> // needed when compiled with -std=c++23
#endif

The __STDC_VERSION__ macro will expand to a similar value, specifying a C standard used. Official docs.

发布评论

评论列表(0)

  1. 暂无评论