[HN Gopher] Cross Language interfaces between C and C++ (2017)
       ___________________________________________________________________
        
       Cross Language interfaces between C and C++ (2017)
        
       Author : signa11
       Score  : 29 points
       Date   : 2021-01-13 09:51 UTC (13 hours ago)
        
 (HTM) web link (gustedt.wordpress.com)
 (TXT) w3m dump (gustedt.wordpress.com)
        
       | [deleted]
        
       | qalmakka wrote:
       | Doesn't this mostly boil down to "C99 and C++ aren't compatible
       | anymore"?
       | 
       | One of the big gotchas of C++ is that lots of people think it's a
       | superset of C, but that's only (mostly) correct for ANSI C (C89).
       | 
       | In my experience not even C99 is completely compatible with C89.
       | One of the initial pain points when clang was young was that GCC
       | used C89 as default, so lots of old stuff didn't build out of the
       | box due to changes to how `inline` behaves or undefined symbols
       | not being allowed anymore.
        
         | ncmncm wrote:
         | C99 is not the current C Standard. C11/C17 have more-or-less
         | deprecated the conflicting bit (VLAs) and C++20 adopted some of
         | C's extensions. So, things are better.
        
       | SloopJon wrote:
       | In order to compile the ratpak library from Microsoft's
       | calculator using Clang, I ported part of it from C++ to C. It's
       | written in C++17 with some C features that only Visual C++
       | accepts. Off the top of my head, some of the changes I needed:
       | 
       | * add extern "C" to some of the headers
       | 
       | * include stdbool.h for bool
       | 
       | * include stdint.h for uint64_t et al.
       | 
       | * include stdlib.h and change nullptr to NULL
       | 
       | * change constexpr to enum
       | 
       | * change static_cast to C-style casts
       | 
       | * rewrite a function to take a pointer, rather than a reference
       | 
       | * write a min() function
       | 
       | I probably could have rewritten it as standard C++, but that
       | somehow seemed like a more daunting prospect at the time.
        
       | jcelerier wrote:
       | The text in the <includes> has been eaten out by the blog engine
       | it seems. To have bool in C it's <stdbool.h> if anyone wonders.
       | 
       | Also regarding generic constants, C++ allows template variables:
       | 
       | https://en.cppreference.com/w/cpp/language/variable_template
        
         | klmr wrote:
         | Same for the templates, presumably; `std::atomic` isn't a type
         | in C++, it's a template. To be analogous with the C code, this
         | was probably meant to read `std::atomic<unsigned>`.
        
         | hoseja wrote:
         | Also all the C++ template parameters, such as
         | std::complex<float>.
        
       | quietbritishjim wrote:
       | > In C [enumeration constants] are of type int, C++ they are of
       | the enumeration type itself.
       | 
       | > ... C and C++ have different rules for implicit conversion from
       | an to these types, so you better avoid using them [in function
       | parameters]
       | 
       | Correct me if I misunderstood, but don't these differences cancel
       | each other out? For example:                   /* In header file
       | */         enum Foo { FOO_A, FOO_B };         void bar(Foo f);
       | /* In code */         bar(FOO_A);
       | 
       | In C, FOO_A is an integer, but it's implicitly convertable to Foo
       | so the call to bar is fine. In C++, int cannot implicitly convert
       | to type Foo, but FOO_A is already of type Foo to begin with, so
       | the function call is still fine. (In fact the call to bar() would
       | in a .c or .cpp file so is allowed to be different between the
       | two languages anyway.)
       | 
       | Edit: Another oddity in the article: If you want a function to
       | work with a small number of different types, you would surely use
       | simple function overloading rather than function template
       | specialisation. In general it's a mistake to use function
       | template specialisation, and there's certainly no need to use it
       | here.
        
         | goodcanadian wrote:
         | I believe:                 enum Foo { FOO_A, FOO_B };
         | 
         | is implicitly convertible to int even in C++.
         | enum class Foo { FOO_A, FOO_B };
         | 
         | is not implicitly convertible, but can still be converted using
         | static_cast.
        
           | [deleted]
        
           | quietbritishjim wrote:
           | Indeed, but I'm talking about the other way: int -> Foo. The
           | article talked about "different rules for implicit
           | conversion" so I assume they must have been referring to that
           | direction.
        
           | qalmakka wrote:
           | This. Only `enum class` gives you a strongly-typed guarantee,
           | `enum` can happily implicitly decay to `int` without any kind
           | of warning. Lots of C libraries use `int` frequently together
           | with enums without any sort of care, and it's too late to
           | change this behaviour without creating an interoperability
           | nightmare. The fact that `int` is not implicitly convertible
           | to an enum type at least still saves you from a death from
           | thousand cuts when a wrong value manages to get into an enum.
           | 
           | The only sane way is to consider `enum` as a deprecated
           | construct in C++ and use it as sparingly as possible,
           | preferably only when interoperability with C makes them
           | unavoidable.
        
             | quietbritishjim wrote:
             | This article is about code that will directly be compiled
             | by both a C and C++ compiler, so indeed `enum class` is not
             | an option here.
        
       ___________________________________________________________________
       (page generated 2021-01-13 23:03 UTC)