• Can extern "C" functions throw exceptions

    From David Brown@21:1/5 to Alf P. Steinbach on Sat Sep 11 20:10:16 2021
    On 11/09/2021 13:55, Alf P. Steinbach wrote:
    On 11 Sep 2021 12:35, Bonita Montero wrote:
    Is it specified that extern "C" functions never throw exceptions.

    No, I don't think so, but that's a common and reasonable assumption.


    extern "C" marks the function as having C naming conventions and C
    calling conventions (which may, in theory, differ from C++ conventions -
    though I have never heard of that in practice). But there is nothing to
    stop a C++ function being marked extern "C" - I have done that in my own
    code, in connection with overriding weak alias functions defined in C or
    when I needed a non-mangled name for the function.

    If we are talking about external C functions - functions compiled in a C
    unit by a C compiler - then it is reasonable to assume that the function
    itself will not throw any exceptions. You'd need C compiler extensions
    to support that. However, the C function could call C++ functions that
    in turn throw exceptions - the external C function would then be passing
    on exceptions, even though it did not throw any itself.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to All on Sun Sep 12 12:34:43 2021
    12.09.2021 12:20 Juha Nieminen kirjutas:
    David Brown <david.brown@hesbynett.no> wrote:
    extern "C" marks the function as having C naming conventions and C
    calling conventions

    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    But that makes me wonder: If an extern "C" declared function has
    C++ types as parameters (or return value type), how are those
    encoded in the name? Or are they at all?

    They aren't.

    Can you overload extern "C"
    functions?

    No.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Juha Nieminen@21:1/5 to David Brown on Sun Sep 12 09:20:23 2021
    David Brown <david.brown@hesbynett.no> wrote:
    extern "C" marks the function as having C naming conventions and C
    calling conventions

    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    But that makes me wonder: If an extern "C" declared function has
    C++ types as parameters (or return value type), how are those
    encoded in the name? Or are they at all? Can you overload extern "C"
    functions?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bonita Montero@21:1/5 to All on Sun Sep 12 12:29:51 2021
    Am 12.09.2021 um 12:24 schrieb David Brown:

    Although in theory a compiler can support different ABI's or calling conventions for C and C++ functions, in practice making a function
    extern "C" simply disables all name mangling for the function. That
    in turn means you can't overload it, or have it in a namespace.

    You can actually define it in a namespace, but it won't belong to it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Juha Nieminen on Sun Sep 12 12:24:35 2021
    On 12/09/2021 11:20, Juha Nieminen wrote:
    David Brown <david.brown@hesbynett.no> wrote:
    extern "C" marks the function as having C naming conventions and C
    calling conventions

    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    But that makes me wonder: If an extern "C" declared function has
    C++ types as parameters (or return value type), how are those
    encoded in the name?

    They are not.

    Or are they at all? Can you overload extern "C"
    functions?


    No.

    Although in theory a compiler can support different ABI's or calling conventions for C and C++ functions, in practice making a function
    extern "C" simply disables all name mangling for the function. That in
    turn means you can't overload it, or have it in a namespace.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Vine@21:1/5 to Juha Nieminen on Sun Sep 12 14:44:43 2021
    On Sun, 12 Sep 2021 09:20:23 -0000 (UTC)
    Juha Nieminen <nospam@thanks.invalid> wrote:
    David Brown <david.brown@hesbynett.no> wrote:
    extern "C" marks the function as having C naming conventions and C
    calling conventions

    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    For functions, it does more than affecting naming. The language linkage
    of a function determines two things: the function's name (name mangling)
    and the function's type (calling convention). For example a function
    pointer has language linkage for its function type even though name
    mangling is irrelevant to it (save as mentioned further below with
    respect to variable names). gcc allows you to pass a function pointer
    with C++ language linkage to a C function expecting a C function
    pointer, but strictly speaking it is undefined behaviour. I believe
    some of the intel compilers did indeed have a different calling
    convention as respects use of registers as between C and C++ functions.

    But that makes me wonder: If an extern "C" declared function has
    C++ types as parameters (or return value type), how are those
    encoded in the name? Or are they at all? Can you overload extern "C" functions?

    In C++ variables also have a language linkage ("All function types,
    function names with external linkage, and variable names with external
    linkage have a language linkage"). But I know of no compiler which
    actually does distinguish between the language linkage of C and C++
    variable names. Function pointers which are lvalues have a language
    linkage with respect to the variable name (if any) of the pointer and as regards the type (calling convention) of the pointed-to function. As mentioned, the language linkage of the variable name is in practice
    immaterial.

    Functions with C language linkage cannot be overridden because name
    mangling is suppressed by C name mangling (the prepending of an
    underscore). As regards argument types, of necessity the only function
    with C language linkage which could take, say, a std::string argument
    is a C++ function declared to have C language linkage.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Chris Vine on Sun Sep 12 23:13:47 2021
    On 9/12/21 9:44 AM, Chris Vine wrote:
    On Sun, 12 Sep 2021 09:20:23 -0000 (UTC)
    Juha Nieminen <nospam@thanks.invalid> wrote:
    ...
    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    For functions, it does more than affecting naming. The language linkage
    of a function determines two things: the function's name (name mangling)
    and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are separable
    by using a typedef for a function's type. The language linkage of the
    typedef determines the calling convention, while the language linkage of
    the function itself determines the name mangling.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Juha Nieminen@21:1/5 to Chris Vine on Mon Sep 13 05:34:18 2021
    Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
    gcc allows you to pass a function pointer
    with C++ language linkage to a C function expecting a C function
    pointer, but strictly speaking it is undefined behaviour.

    Does that mean that if you are using a C library and you give it a
    function pointer (eg. a callback function), you ought to make that
    function extern "C"?

    How about std::qsort()? Does its comparator function pointer need to be declared extern "C"? (Or does the standard require std::qsort() to be
    usable with C++ function pointers directly?)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to All on Mon Sep 13 09:55:06 2021
    13.09.2021 08:34 Juha Nieminen kirjutas:
    Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
    gcc allows you to pass a function pointer
    with C++ language linkage to a C function expecting a C function
    pointer, but strictly speaking it is undefined behaviour.

    Does that mean that if you are using a C library and you give it a
    function pointer (eg. a callback function), you ought to make that
    function extern "C"?

    Strictly speaking, yes, otherwise the calling conventions might be mixed
    up. But meanstream C++ implementations are using the same calling
    conventions for C and C++ code, so they don't mind.


    How about std::qsort()? Does its comparator function pointer need to be declared extern "C"? (Or does the standard require std::qsort() to be
    usable with C++ function pointers directly?)

    Indeed, the C++ standard requires qsort to accept both C and C++
    callbacks. This is a copy-paste from N4842:

    void qsort(void* base, size_t nmemb, size_t size, c-compare-pred * compar); void qsort(void* base, size_t nmemb, size_t size, compare-pred * compar);

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to James Kuyper on Mon Sep 13 09:30:27 2021
    On 13/09/2021 05:13, James Kuyper wrote:
    On 9/12/21 9:44 AM, Chris Vine wrote:
    On Sun, 12 Sep 2021 09:20:23 -0000 (UTC)
    Juha Nieminen <nospam@thanks.invalid> wrote:
    ...
    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    For functions, it does more than affecting naming. The language linkage
    of a function determines two things: the function's name (name mangling)
    and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are separable
    by using a typedef for a function's type. The language linkage of the
    typedef determines the calling convention, while the language linkage of
    the function itself determines the name mangling.


    That is not something I knew.

    It does not affect my own coding, as I know the ABI's are the same for C
    and C++ and everything is handled by the same compiler. But it might be relevant in odd cases.

    One thing that might be relevant in the future is some of the ideas
    being considered for changing exceptions into a simpler and more
    deterministic system, with far lower overheads, clearer code and better checking by making them more static and less run-time. Some of the
    papers around this have suggested using additional registers or
    processor flags as cheap ways to return exception information to the
    caller - and that might mean a change to the C++ ABI compared to the C
    ABI on the same platform, even for otherwise simple function parameters.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From red floyd@21:1/5 to Bonita Montero on Mon Sep 13 13:21:33 2021
    On 9/11/2021 3:35 AM, Bonita Montero wrote:
    Is it specified that extern "C" functions never throw exceptions.
    If it is I see a problem with this: if I pass a function-pointer
    to a C++-function an extern "C" function and this function is
    called through its pointer by the extern "C" function it might
    throw an exception.

    I can see how the following case might throw....

    Disclaimer: I have no idea what the Standard says about it.


    class C
    {
    public:
    static void i_throw()
    {
    throw 1;
    }
    };

    extern "C" throwing_c_func()
    {
    C::i_throw();
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to James Kuyper on Wed Oct 6 13:12:42 2021
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    On 9/12/21 9:44 AM, Chris Vine wrote:

    On Sun, 12 Sep 2021 09:20:23 -0000 (UTC)
    Juha Nieminen <nospam@thanks.invalid> wrote:

    ...

    Indeed, extern "C" doesn't mean that the code being called using
    those functions has actually been compiled as C. It merely changes
    the naming of the functions in the object files to be compatible
    with how functions are named in C.

    For functions, it does more than affecting naming. The language
    linkage of a function determines two things: the function's name
    (name mangling) and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are
    separable by using a typedef for a function's type. The language
    linkage of the typedef determines the calling convention, while the
    language linkage of the function itself determines the name
    mangling.

    Can you illustrate how that would be done? Since the language
    linkage of a function is part of its type, it sounds like trying
    to do such a thing would inevitably lead to undefined behavior.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From danielaparker@gmail.com@21:1/5 to Alf P. Steinbach on Wed Oct 6 13:36:51 2021
    On Saturday, September 11, 2021 at 11:00:42 AM UTC-4, Alf P. Steinbach wrote:

    And these are the guys creating a Windows calculator
    that by default evaluates 2+3*4 as (2+3)*4.

    In Standard mode, but not in Scientific or Programmer mode :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Branimir Maksimovic@21:1/5 to daniel...@gmail.com on Wed Oct 6 20:42:07 2021
    On 2021-10-06, daniel...@gmail.com <danielaparker@gmail.com> wrote:
    On Saturday, September 11, 2021 at 11:00:42 AM UTC-4, Alf P. Steinbach wrote:

    And these are the guys creating a Windows calculator
    that by default evaluates 2+3*4 as (2+3)*4.

    In Standard mode, but not in Scientific or Programmer mode :-)
    --main = print $ calculate "3 * 2 + 5 / 2"

    calculate :: String -> String
    calculate str = case (eval operatorRegister . words) str of
    Just r -> printf "%.2f" (fromRational r::Double)
    Nothing -> "Nothing"

    eval :: Register -> [String] -> Maybe Rational
    eval [] _ = Nothing -- No operator found.
    eval _ [] = Nothing -- If a operator don't have anything to operate on.
    eval _ [number] = let a :: Maybe Double = readMaybe number
    in case a of
    Just a -> Just (toRational a)
    Nothing -> Nothing
    eval ((operator, function):rest) unparsed =
    case span (/=operator) unparsed of
    (_, []) -> eval rest unparsed
    (beforeOperator, afterOperator) ->
    function
    <$> (eval operatorRegister beforeOperator)
    <*> (eval operatorRegister $ drop 1 afterOperator)


    --

    7-77-777
    Evil Sinner!
    to weak you should be meek, and you should brainfuck stronger https://github.com/rofl0r/chaos-pp

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Keith Thompson@21:1/5 to Branimir Maksimovic on Wed Oct 6 16:12:53 2021
    Branimir Maksimovic <branimir.maksimovic@icloud.com> writes:
    On 2021-10-06, daniel...@gmail.com <danielaparker@gmail.com> wrote:
    On Saturday, September 11, 2021 at 11:00:42 AM UTC-4, Alf P. Steinbach wrote:

    And these are the guys creating a Windows calculator
    that by default evaluates 2+3*4 as (2+3)*4.

    In Standard mode, but not in Scientific or Programmer mode :-)
    --main = print $ calculate "3 * 2 + 5 / 2"

    calculate :: String -> String
    calculate str = case (eval operatorRegister . words) str of
    Just r -> printf "%.2f" (fromRational r::Double)
    Nothing -> "Nothing"

    eval :: Register -> [String] -> Maybe Rational
    eval [] _ = Nothing -- No operator found.
    eval _ [] = Nothing -- If a operator don't have anything to operate on.
    eval _ [number] = let a :: Maybe Double = readMaybe number
    in case a of
    Just a -> Just (toRational a)
    Nothing -> Nothing
    eval ((operator, function):rest) unparsed =
    case span (/=operator) unparsed of
    (_, []) -> eval rest unparsed
    (beforeOperator, afterOperator) ->
    function
    <$> (eval operatorRegister beforeOperator)
    <*> (eval operatorRegister $ drop 1 afterOperator)

    I don't know what language that is, and you haven't bothered to tell us.
    (No, I'm not asking, just saying that whatever point your post might
    have is defeated by not knowing what language you're using.)

    Again, you've posted something that isn't relevant either to the subject
    of this newsgroup (the C++ language) or to the thread (which is about
    extern "C" functions throwing exceptions, with a passing reference to
    the Windows calculator program).

    This kind of thing is a problem. I can solve it for myself by
    configuring my newsreader to stop showing me your posts. You can solve
    it for everyone by not making off-topic posts. (The fact that you post
    obscure things without any explanation is just icing on the unpleasant
    cake.) Please don't just post whatever you think is interesting.
    Consider whether it's appropriate.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    Working, but not speaking, for Philips
    void Void(void) { Void(); } /* The recursive call of the void */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Keith Thompson@21:1/5 to Branimir Maksimovic on Wed Oct 6 17:03:49 2021
    Branimir Maksimovic <branimir.maksimovic@icloud.com> writes:
    On 2021-10-06, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    [...]
    Again, you've posted something that isn't relevant either to the subject
    of this newsgroup (the C++ language) or to the thread (which is about
    extern "C" functions throwing exceptions, with a passing reference to
    the Windows calculator program).

    Who cares, this is not *mderated* group, you just embarrased yourself
    not recognizing simple calculator in Haskell :P

    I care, and most readers here do as well.

    Consider whether it's appropriate.

    It is talk was about calculator :p

    *PLONK*

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    Working, but not speaking, for Philips
    void Void(void) { Void(); } /* The recursive call of the void */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Branimir Maksimovic@21:1/5 to Keith Thompson on Wed Oct 6 23:22:52 2021
    On 2021-10-06, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    Branimir Maksimovic <branimir.maksimovic@icloud.com> writes:
    On 2021-10-06, daniel...@gmail.com <danielaparker@gmail.com> wrote:
    On Saturday, September 11, 2021 at 11:00:42 AM UTC-4, Alf P. Steinbach wrote:

    And these are the guys creating a Windows calculator
    that by default evaluates 2+3*4 as (2+3)*4.

    In Standard mode, but not in Scientific or Programmer mode :-)
    --main = print $ calculate "3 * 2 + 5 / 2"

    calculate :: String -> String
    calculate str = case (eval operatorRegister . words) str of
    Just r -> printf "%.2f" (fromRational r::Double)
    Nothing -> "Nothing"

    eval :: Register -> [String] -> Maybe Rational
    eval [] _ = Nothing -- No operator found.
    eval _ [] = Nothing -- If a operator don't have anything to operate on.
    eval _ [number] = let a :: Maybe Double = readMaybe number
    in case a of
    Just a -> Just (toRational a)
    Nothing -> Nothing
    eval ((operator, function):rest) unparsed =
    case span (/=operator) unparsed of
    (_, []) -> eval rest unparsed
    (beforeOperator, afterOperator) ->
    function
    <$> (eval operatorRegister beforeOperator)
    <*> (eval operatorRegister $ drop 1 afterOperator)

    I don't know what language that is, and you haven't bothered to tell us.
    (No, I'm not asking, just saying that whatever point your post might
    have is defeated by not knowing what language you're using.)


    Petty, one of the favorite Hacker languages :P
    (Haskell) , besides /forth and ASSE/mbler :P

    Again, you've posted something that isn't relevant either to the subject
    of this newsgroup (the C++ language) or to the thread (which is about
    extern "C" functions throwing exceptions, with a passing reference to
    the Windows calculator program).


    Who cares, this is not *mderated* group, you just embarrased yourself
    not recognizing simple calculator in Haskell :P

    Consider whether it's appropriate.

    It is talk was about calculator :p

    --

    7-77-777
    Evil Sinner!
    to weak you should be meek, and you should brainfuck stronger https://github.com/rofl0r/chaos-pp

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jameskuyper@alumni.caltech.edu@21:1/5 to Tim Rentsch on Thu Oct 7 07:09:07 2021
    On Wednesday, October 6, 2021 at 4:12:52 PM UTC-4, Tim Rentsch wrote:
    James Kuyper <james...@alumni.caltech.edu> writes:

    On 9/12/21 9:44 AM, Chris Vine wrote:
    ...
    For functions, it does more than affecting naming. The language
    linkage of a function determines two things: the function's name
    (name mangling) and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are
    separable by using a typedef for a function's type. The language
    linkage of the typedef determines the calling convention, while the language linkage of the function itself determines the name
    mangling.
    Can you illustrate how that would be done? Since the language
    linkage of a function is part of its type, it sounds like trying
    to do such a thing would inevitably lead to undefined behavior.

    The language linkage of a function's type is indeed part of that type. The language linkage of a function's name is not. The standard's description of language linkage in 9.11p1 starts with the sentence "All function types, function names with external linkage, and variable names with external
    linkage have a language linkage.", clearly making the point that the
    language linkage of a function's type is a distinct thing from the language linkage of a function's name. The standard could have inextricably linked
    them together - but it does not. In fact, 9.11p5 includes an example demonstrating how they can be separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function’s type has C language linkage

    Now, the standard can and does contain example code that violates a C++
    rule, as a way of explaining what that rule means. However, when it does so,
    it almost always includes a comment next to the offending line pointing out that it violates a rule. There's no such comment in this example. In fact, the only comments explicitly describe the well-defined meaning of that code.

    All quotes are from n4860.pdf, the latest draft version of the C++ language that I have access to. However, this is not a new feature of the language; it has been part of standard C++ for as long as C++ has been standardized.
    I'm not sure about pre-standard C++ - my copy of Stroustrup's book went
    missing many years ago.

    The C++ language linkage of f2's name means that it can be referred to by
    name in C++ code, but not in C code. The C language linkage of f2's type
    means that f2 can called from C as well as from C++. However, since the function's name can't be referred to by C code, it must be called using a pointer, and that pointer's value can only come from C++ code. It could be passed to the C part of a program as a function parameter, or returned as
    the value of a function call, or placed in a function pointer object shared between the C and C++ parts of a program.

    I don't see any reasonable use for the opposite: a function whose name has
    C language linkage and whose type has C++ language linkage. C has no way
    of correctly declaring the type of the function associated with that name,
    and the function's name cannot be declared without specifying it's type.
    Such a function would be callable by name from C++ but I don't see any particular advantage of that.

    I don't think that the ability to separate the language linkage of a function's type from the language linkage of the function's name was a strongly desired feature in itself. I suspect that it is simply a side-effect that arose naturally
    from the fact that those are two different aspects of language linkage, combined with the way typedefs work.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to james...@alumni.caltech.edu on Tue Dec 14 15:21:21 2021
    "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> writes:

    On Wednesday, October 6, 2021 at 4:12:52 PM UTC-4, Tim Rentsch wrote:

    James Kuyper <james...@alumni.caltech.edu> writes:

    On 9/12/21 9:44 AM, Chris Vine wrote:

    ...

    For functions, it does more than affecting naming. The language
    linkage of a function determines two things: the function's name
    (name mangling) and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are
    separable by using a typedef for a function's type. The language
    linkage of the typedef determines the calling convention, while the
    language linkage of the function itself determines the name
    mangling.

    Can you illustrate how that would be done? Since the language
    linkage of a function is part of its type, it sounds like trying
    to do such a thing would inevitably lead to undefined behavior.

    The language linkage of a function's type is indeed part of that type. The language linkage of a function's name is not. The standard's description of language linkage in 9.11p1 starts with the sentence "All function types, function names with external linkage, and variable names with external linkage have a language linkage.", clearly making the point that the
    language linkage of a function's type is a distinct thing from the language linkage of a function's name. The standard could have inextricably linked them together - but it does not. In fact, 9.11p5 includes an example demonstrating how they can be separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    It appears, however, that in practice there is no difference
    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jameskuyper@alumni.caltech.edu@21:1/5 to Tim Rentsch on Tue Dec 14 19:06:55 2021
    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:
    "james...@alumni.caltech.edu" <james...@alumni.caltech.edu> writes:
    ...
    The language linkage of a function's type is indeed part of that type. The language linkage of a function's name is not. The standard's description of language linkage in 9.11p1 starts with the sentence "All function types, function names with external linkage, and variable names with external linkage have a language linkage.", clearly making the point that the language linkage of a function's type is a distinct thing from the language linkage of a function's name. The standard could have inextricably linked them together - but it does not. In fact, 9.11p5 includes an example demonstrating how they can be separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    If you can figure out words to express your remaining questions, I'd be curious to find out what they are.

    It appears, however, that in practice there is no difference
    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/ is-extern-c-a-part-of-the-type-of-a-function

    The standard is quite clear: "Two function types with different language linkages are distinct types even if they are otherwise identical." (9.11p1). I'm
    annoyed, but unfortunately not surprised, to find that this has been ignored. I've never had any need to write code where that issue would matter, which
    is why I've never noticed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Tim Rentsch on Tue Dec 14 21:17:35 2021
    On 12/14/21 6:21 PM, Tim Rentsch wrote:
    "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> writes:

    On Wednesday, October 6, 2021 at 4:12:52 PM UTC-4, Tim Rentsch wrote:

    James Kuyper <james...@alumni.caltech.edu> writes:

    On 9/12/21 9:44 AM, Chris Vine wrote:

    ...

    For functions, it does more than affecting naming. The language
    linkage of a function determines two things: the function's name
    (name mangling) and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are
    separable by using a typedef for a function's type. The language
    linkage of the typedef determines the calling convention, while the
    language linkage of the function itself determines the name
    mangling.

    Can you illustrate how that would be done? Since the language
    linkage of a function is part of its type, it sounds like trying
    to do such a thing would inevitably lead to undefined behavior.

    The language linkage of a function's type is indeed part of that type. The >> language linkage of a function's name is not. The standard's description of >> language linkage in 9.11p1 starts with the sentence "All function types,
    function names with external linkage, and variable names with external
    linkage have a language linkage.", clearly making the point that the
    language linkage of a function's type is a distinct thing from the language >> linkage of a function's name. The standard could have inextricably linked >> them together - but it does not. In fact, 9.11p5 includes an example
    demonstrating how they can be separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    It appears, however, that in practice there is no difference
    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function


    Maybe a better way of saying that is most platform ABIs don't allow for
    a difference, because it would break too much existing code.

    Few implementations are designed in a vacuum, most have an ABI they need
    to conform to (or multiple ones to select between with options).

    Only when a brand new platform comes out do we have the ability to
    really inovate on an ABI, and even then inertia tends to restrict it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ian Collins@21:1/5 to james...@alumni.caltech.edu on Thu Dec 16 13:14:11 2021
    On 15/12/2021 16:06, james...@alumni.caltech.edu wrote:
    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:
    "james...@alumni.caltech.edu" <james...@alumni.caltech.edu> writes:
    ...
    The language linkage of a function's type is indeed part of that type. The >>> language linkage of a function's name is not. The standard's description of >>> language linkage in 9.11p1 starts with the sentence "All function types, >>> function names with external linkage, and variable names with external
    linkage have a language linkage.", clearly making the point that the
    language linkage of a function's type is a distinct thing from the language >>> linkage of a function's name. The standard could have inextricably linked >>> them together - but it does not. In fact, 9.11p5 includes an example
    demonstrating how they can be separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    If you can figure out words to express your remaining questions, I'd be curious
    to find out what they are.

    It appears, however, that in practice there is no difference
    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    The standard is quite clear: "Two function types with different language linkages are distinct types even if they are otherwise identical." (9.11p1). I'm
    annoyed, but unfortunately not surprised, to find that this has been ignored. I've never had any need to write code where that issue would matter, which
    is why I've never noticed.

    I have only used one compiler, Sun CC, that bothered to enforce the
    rule. At the time, the main problem this caused me was it prevented
    static member functions being passed to pthread_create, I had to use
    extern "C" qualified friend function on Solaris.

    --
    Ian.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris M. Thomasson@21:1/5 to Ian Collins on Wed Dec 15 18:05:24 2021
    On 12/15/2021 4:14 PM, Ian Collins wrote:
    On 15/12/2021 16:06, james...@alumni.caltech.edu wrote:
    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:
    "james...@alumni.caltech.edu" <james...@alumni.caltech.edu> writes:
    [...]
    I have only used one compiler, Sun CC, that bothered to enforce the
    rule.  At the time, the main problem this caused me was it prevented
    static member functions being passed to pthread_create, I had to use
    extern "C" qualified friend function on Solaris.


    I remember that! I was using Solaris during Sun's CoolThreads contest.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to james...@alumni.caltech.edu on Thu Dec 16 04:29:28 2021
    "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> writes:

    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:

    "james...@alumni.caltech.edu" <james...@alumni.caltech.edu> writes:

    ...

    The language linkage of a function's type is indeed part of that
    type. The language linkage of a function's name is not. The
    standard's description of language linkage in 9.11p1 starts with
    the sentence "All function types, function names with external
    linkage, and variable names with external linkage have a
    language linkage.", clearly making the point that the language
    linkage of a function's type is a distinct thing from the
    language linkage of a function's name. The standard could have
    inextricably linked them together - but it does not. In fact,
    9.11p5 includes an example demonstrating how they can be
    separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    If you can figure out words to express your remaining questions,
    I'd be curious to find out what they are.

    At this point I'm not sure what the other questions are. And since
    I don't have any way to test various scenarios (or at least not any
    convenient way), for now it seems best just to stop here.

    It appears, however, that in practice there is no difference
    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    The standard is quite clear: "Two function types with different
    language linkages are distinct types even if they are otherwise
    identical." (9.11p1). [...]

    Yes, I think that very sentence was quoted in the stackoverflow
    page.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Ian Collins on Thu Dec 16 04:37:17 2021
    Ian Collins <ian-news@hotmail.com> writes:

    On 15/12/2021 16:06, james...@alumni.caltech.edu wrote:

    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:

    "james...@alumni.caltech.edu" <james...@alumni.caltech.edu> writes:

    ...

    The language linkage of a function's type is indeed part of
    that type. The language linkage of a function's name is not.
    The standard's description of language linkage in 9.11p1 starts
    with the sentence "All function types, function names with
    external linkage, and variable names with external linkage have
    a language linkage.", clearly making the point that the
    language linkage of a function's type is a distinct thing from
    the language linkage of a function's name. The standard could
    have inextricably linked them together - but it does not. In
    fact, 9.11p5 includes an example demonstrating how they can be
    separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    If you can figure out words to express your remaining questions,
    I'd be curious to find out what they are.
    >> It appears, however, that in practice there is no difference

    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    The standard is quite clear: "Two function types with different
    language linkages are distinct types even if they are otherwise
    identical." (9.11p1). I'm annoyed, but unfortunately not
    surprised, to find that this has been ignored. I've never had
    any need to write code where that issue would matter, which is
    why I've never noticed.

    I have only used one compiler, Sun CC, that bothered to enforce
    the rule. At the time, the main problem this caused me was it
    prevented static member functions being passed to pthread_create,
    I had to use extern "C" qualified friend function on Solaris.

    Did you try a pattern like this:

    extern "C" typedef void Whatsit( double * );

    class Foo {
    public:
    static Whatsit fred;
    };

    void
    Foo::fred( double *things ){
    for( int i = 0; i < 10; i++ ) things[i] += i;
    }

    This code is accepted by g++ back to -std=c++98. Of course,
    since we know the gnu tools are compromised that doesn't tell us
    very much...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Richard Damon on Thu Dec 16 04:21:05 2021
    Richard Damon <Richard@Damon-Family.org> writes:

    On 12/14/21 6:21 PM, Tim Rentsch wrote:

    "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> writes:

    On Wednesday, October 6, 2021 at 4:12:52 PM UTC-4, Tim Rentsch wrote:

    James Kuyper <james...@alumni.caltech.edu> writes:

    On 9/12/21 9:44 AM, Chris Vine wrote:

    ...

    For functions, it does more than affecting naming. The language
    linkage of a function determines two things: the function's name
    (name mangling) and the function's type (calling convention).

    Furthermore, and not widely appreciated, those two aspects are
    separable by using a typedef for a function's type. The language
    linkage of the typedef determines the calling convention, while
    the language linkage of the function itself determines the name
    mangling.

    Can you illustrate how that would be done? Since the language
    linkage of a function is part of its type, it sounds like trying
    to do such a thing would inevitably lead to undefined behavior.

    The language linkage of a function's type is indeed part of that
    type. The language linkage of a function's name is not. The
    standard's description of language linkage in 9.11p1 starts with
    the sentence "All function types, function names with external
    linkage, and variable names with external linkage have a language
    linkage.", clearly making the point that the language linkage of a
    function's type is a distinct thing from the language linkage of a
    function's name. The standard could have inextricably linked them
    together - but it does not. In fact, 9.11p5 includes an example
    demonstrating how they can be separated:

    extern "C" typedef void FUNC();
    FUNC f2; // the name f2 has C ++ language linkage and the
    // function?s type has C language linkage

    [...]

    Thank you for this citation. It doesn't answer all my questions
    but it certainly does provide an illuminating example.

    It appears, however, that in practice there is no difference
    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    Maybe a better way of saying that is most platform ABIs don't allow
    for a difference, because it would break too much existing code.

    If the compiler had been doing its job all along then it wouldn't
    break any code. The whole point of having language linkage be
    part of the type is to accommodate different ABIs for the two
    languages, without having to worry about using the wrong one
    because any violations would be caught by the type checker.

    Furthermore, even if the ABIs are the same, the language standard
    requires a diagnostic, so any C++ implementation should at least
    give a warning. If I give a -pedantic option then I expect
    (wrongly it seems) that all language rules will be faithfully
    observed. Apparently -pedantic means "we're going to follow all
    the rules that we think are worth following." And to the best of
    my knowledge clang is no better than gcc in this respect. Very
    disappointing.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ian Collins@21:1/5 to Tim Rentsch on Fri Dec 17 09:39:33 2021
    On 17/12/2021 01:37, Tim Rentsch wrote:
    Ian Collins <ian-news@hotmail.com> writes:

    On 15/12/2021 16:06, james...@alumni.caltech.edu wrote:

    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:

    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    The standard is quite clear: "Two function types with different
    language linkages are distinct types even if they are otherwise
    identical." (9.11p1). I'm annoyed, but unfortunately not
    surprised, to find that this has been ignored. I've never had
    any need to write code where that issue would matter, which is
    why I've never noticed.

    I have only used one compiler, Sun CC, that bothered to enforce
    the rule. At the time, the main problem this caused me was it
    prevented static member functions being passed to pthread_create,
    I had to use extern "C" qualified friend function on Solaris.

    Did you try a pattern like this:

    extern "C" typedef void Whatsit( double * );

    class Foo {
    public:
    static Whatsit fred;
    };

    void
    Foo::fred( double *things ){
    for( int i = 0; i < 10; i++ ) things[i] += i;
    }

    This code is accepted by g++ back to -std=c++98. Of course,
    since we know the gnu tools are compromised that doesn't tell us
    very much...

    No, I just used friend unctions, your suggestion would have been
    interesting to try, but I no longer have those tools installed.

    --
    Ian.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Ian Collins on Thu Dec 16 19:24:21 2021
    Ian Collins <ian-news@hotmail.com> writes:

    On 17/12/2021 01:37, Tim Rentsch wrote:

    Ian Collins <ian-news@hotmail.com> writes:

    On 15/12/2021 16:06, james...@alumni.caltech.edu wrote:

    On Tuesday, December 14, 2021 at 6:21:38 PM UTC-5, Tim Rentsch wrote:

    between a type with a C language linkage and a C++ language
    linkage. Apparently most compilers ignore the distinction
    because following the rules would break too much code. Here
    is a link to stackoverflow with more information:

    https://stackoverflow.com/questions/26647259/
    is-extern-c-a-part-of-the-type-of-a-function

    The standard is quite clear: "Two function types with different
    language linkages are distinct types even if they are otherwise
    identical." (9.11p1). I'm annoyed, but unfortunately not
    surprised, to find that this has been ignored. I've never had
    any need to write code where that issue would matter, which is
    why I've never noticed.

    I have only used one compiler, Sun CC, that bothered to enforce
    the rule. At the time, the main problem this caused me was it
    prevented static member functions being passed to pthread_create,
    I had to use extern "C" qualified friend function on Solaris.

    Did you try a pattern like this:

    extern "C" typedef void Whatsit( double * );

    class Foo {
    public:
    static Whatsit fred;
    };

    void
    Foo::fred( double *things ){
    for( int i = 0; i < 10; i++ ) things[i] += i;
    }

    This code is accepted by g++ back to -std=c++98. Of course,
    since we know the gnu tools are compromised that doesn't tell us
    very much...

    No, I just used friend unctions, your suggestion would have been
    interesting to try, but I no longer have those tools installed.

    Okay, thank you. I was asking only out of curiosity.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)