• Re: Is EXIT_SUCCESS/EXIT_FAILURE necessary?

    From Paavo Helde@21:1/5 to wij on Wed Nov 20 09:22:07 2024
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of programs for some reason, but generally, exit code of program is a numerical value. Why EXIT_SUCCESS?



    EXIT_SUCCESS is an attempt to provide an abstraction which was attempted
    to cover more different platforms than POSIX style exit codes. The idea
    was that one can use EXIT_SUCCESS and EXIT_FAILURE regardless whether
    the program is compiled to run on some Unix, on some weird mainframe
    with weird exit code values, or in some free-standing implementation
    where there is no OS, not to speak about shell scripts.

    Even on Linux or Windows, note that the exit code numeric values
    contradict the conventions of C and C++ where 1 is normally converted to
    true and 0 to false. So to reduce confusion it might be a good idea to
    use the macros even here. Note that nowadays there are many programmers
    (esp. on Windows) who have no idea about program exit code conventions
    or shell scripts.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 20 08:27:11 2024
    On Wed, 20 Nov 2024 09:22:07 +0200
    Paavo Helde <[email protected]> boring babbled:
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >> But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of
    programs for some reason, but generally, exit code of program is a numerical >> value. Why EXIT_SUCCESS?



    EXIT_SUCCESS is an attempt to provide an abstraction which was attempted
    to cover more different platforms than POSIX style exit codes. The idea
    was that one can use EXIT_SUCCESS and EXIT_FAILURE regardless whether
    the program is compiled to run on some Unix, on some weird mainframe
    with weird exit code values, or in some free-standing implementation
    where there is no OS, not to speak about shell scripts.

    Even on Linux or Windows, note that the exit code numeric values
    contradict the conventions of C and C++ where 1 is normally converted to
    true and 0 to false. So to reduce confusion it might be a good idea to
    use the macros even here. Note that nowadays there are many programmers
    (esp. on Windows) who have no idea about program exit code conventions
    or shell scripts.

    Even within Posix return values are inconsistent. Most posix functions
    return -1 for failure, >= 0 for success and set errno, not so the pthread_*() functions which return the errno directly on failure and zero for success.
    A poor decision IMO.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to [email protected] on Wed Nov 20 13:47:53 2024
    [email protected] writes:
    On Wed, 20 Nov 2024 09:22:07 +0200
    Paavo Helde <[email protected]> boring babbled:
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >>> But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of >>> programs for some reason, but generally, exit code of program is a numerical
    value. Why EXIT_SUCCESS?



    EXIT_SUCCESS is an attempt to provide an abstraction which was attempted
    to cover more different platforms than POSIX style exit codes. The idea
    was that one can use EXIT_SUCCESS and EXIT_FAILURE regardless whether
    the program is compiled to run on some Unix, on some weird mainframe
    with weird exit code values, or in some free-standing implementation
    where there is no OS, not to speak about shell scripts.

    Even on Linux or Windows, note that the exit code numeric values
    contradict the conventions of C and C++ where 1 is normally converted to >>true and 0 to false. So to reduce confusion it might be a good idea to
    use the macros even here. Note that nowadays there are many programmers >>(esp. on Windows) who have no idea about program exit code conventions
    or shell scripts.

    Even within Posix return values are inconsistent. Most posix functions
    return -1 for failure, >= 0 for success and set errno, not so the pthread_*() >functions which return the errno directly on failure and zero for success.
    A poor decision IMO.

    Before POSIX.4 was introducted (pthreads), the convention was return -1
    for failure with ERRNO set.

    With the introduction of multi-threaded programs by POSIX.4, the
    convention -for new posix functions- is to return ERRNO directly
    to avoid using the global (or in modern systems thread-specific)
    errno. This was a deliberate choice by the POSIX.4 working group.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to wij on Wed Nov 20 13:44:19 2024
    wij <[email protected]> writes:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of >programs for some reason, but generally, exit code of program is a numerica= >l
    value. Why EXIT_SUCCESS?


    The unix shell interprets the exit code. A script can determine whether
    a command succeeded or failed and take the appropriate action based on
    the exit code. A zero return indicates the command was successful, a
    non-zero return indicates failure.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 20 15:05:52 2024
    On Wed, 20 Nov 2024 13:47:53 GMT
    [email protected] (Scott Lurndal) boring babbled:
    [email protected] writes:
    Even within Posix return values are inconsistent. Most posix functions >>return -1 for failure, >= 0 for success and set errno, not so the pthread_*()

    functions which return the errno directly on failure and zero for success. >>A poor decision IMO.

    Before POSIX.4 was introducted (pthreads), the convention was return -1
    for failure with ERRNO set.

    With the introduction of multi-threaded programs by POSIX.4, the
    convention -for new posix functions- is to return ERRNO directly
    to avoid using the global (or in modern systems thread-specific)
    errno. This was a deliberate choice by the POSIX.4 working group.

    Without changing every other posix function behaviour its a pointless gesture that just causes confusion as errno will still be used elsewhere.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to [email protected] on Wed Nov 20 15:45:03 2024
    [email protected] writes:
    On Wed, 20 Nov 2024 13:47:53 GMT
    [email protected] (Scott Lurndal) boring babbled:
    [email protected] writes:
    Even within Posix return values are inconsistent. Most posix functions >>>return -1 for failure, >= 0 for success and set errno, not so the pthread_*()

    functions which return the errno directly on failure and zero for success. >>>A poor decision IMO.

    Before POSIX.4 was introducted (pthreads), the convention was return -1
    for failure with ERRNO set.

    With the introduction of multi-threaded programs by POSIX.4, the
    convention -for new posix functions- is to return ERRNO directly
    to avoid using the global (or in modern systems thread-specific)
    errno. This was a deliberate choice by the POSIX.4 working group.

    Without changing every other posix function behaviour its a pointless gesture >that just causes confusion as errno will still be used elsewhere.


    That was clearly not the opinion of the POSIX working group.

    Anyone confused by the fact that the interface set is not
    completely uniform probably needs to look for a different
    job if they are unable to RTFM

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to wij on Wed Nov 20 17:23:22 2024
    On Wed, 20 Nov 2024 22:57:25 +0800
    wij <[email protected]> wrote:

    On Wed, 2024-11-20 at 13:44 +0000, Scott Lurndal wrote:
    wij <[email protected]> writes:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. But, is it necessary? E.g. can it be put into shell
    script? I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good
    within a group of programs for some reason, but generally, exit
    code of program is a numerica= l
    value. Why EXIT_SUCCESS?


    The unix shell interprets the exit code.  A script can determine
    whether a command succeeded or failed and take the appropriate
    action based on the exit code.   A zero return indicates the
    command was successful, a non-zero return indicates failure.

    That is my point. Scripts see number not C/C++ symbol EXIT_SUCCESS.
    Programs can be written in various languages. How to make these
    programs read the C/C++ macro "EXIT_SUCCESS"? And, as it is 'POSIX',
    that means All kind of OS should recognize "EXIT_SUCCESS" to be
    portable. I doubt this. IMO, 0 is more portable than EXIT_SUCCESS.
    But, there should be some details I don't know. Besides, defining EXIT_SUCCESS has a draw back that programs will have problem to use a
    range of numbers as exit code. Not allowed? As said I don't know the rationale.




    On POSIX and on many other OSes conventions are like you said. But it
    is not universal. One example of different conventions is VMS.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 20 16:41:14 2024
    On Wed, 20 Nov 2024 15:45:03 GMT
    [email protected] (Scott Lurndal) boring babbled:
    [email protected] writes:
    On Wed, 20 Nov 2024 13:47:53 GMT
    [email protected] (Scott Lurndal) boring babbled: >>>[email protected] writes:
    Even within Posix return values are inconsistent. Most posix functions >>>>return -1 for failure, >= 0 for success and set errno, not so the >pthread_*()

    functions which return the errno directly on failure and zero for success. >>>>A poor decision IMO.

    Before POSIX.4 was introducted (pthreads), the convention was return -1 >>>for failure with ERRNO set.

    With the introduction of multi-threaded programs by POSIX.4, the >>>convention -for new posix functions- is to return ERRNO directly
    to avoid using the global (or in modern systems thread-specific)
    errno. This was a deliberate choice by the POSIX.4 working group.

    Without changing every other posix function behaviour its a pointless gesture >>that just causes confusion as errno will still be used elsewhere.


    That was clearly not the opinion of the POSIX working group.

    Committees don't always make the best decision as the current state of C++ demonstrates.

    Anyone confused by the fact that the interface set is not
    completely uniform probably needs to look for a different
    job if they are unable to RTFM

    If you think consistency within an API is unimportant then I suggest it
    might be you who belongs in another career.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Chris M. Thomasson on Wed Nov 20 22:11:46 2024
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/19/2024 11:22 PM, Paavo Helde wrote:
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different
    programs.
    But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of >>> programs for some reason, but generally, exit code of program is a
    numerical
    value. Why EXIT_SUCCESS?



    EXIT_SUCCESS is an attempt to provide an abstraction which was attempted
    to cover more different platforms than POSIX style exit codes. The idea
    was that one can use EXIT_SUCCESS and EXIT_FAILURE regardless whether
    the program is compiled to run on some Unix, on some weird mainframe
    with weird exit code values, or in some free-standing implementation
    where there is no OS, not to speak about shell scripts.

    Even on Linux or Windows, note that the exit code numeric values
    contradict the conventions of C and C++ where 1 is normally converted to
    true and 0 to false. So to reduce confusion it might be a good idea to
    use the macros even here. Note that nowadays there are many programmers
    (esp. on Windows) who have no idea about program exit code conventions
    or shell scripts.



    EXIT_SUCCESS can be 0xbeefbeef and EXIT_FAILURE can be 0xdeadbeef?


    Not on any POSIX system. EXIT_SUCCESS must be zero. EXIT_FAILURE
    must be between 1 and 125 inclusive.

    https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Chris M. Thomasson on Wed Nov 20 23:03:45 2024
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/19/2024 11:22 PM, Paavo Helde wrote:
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different
    programs.
    But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of >>>>> programs for some reason, but generally, exit code of program is a
    numerical
    value. Why EXIT_SUCCESS?



    EXIT_SUCCESS is an attempt to provide an abstraction which was attempted >>>> to cover more different platforms than POSIX style exit codes. The idea >>>> was that one can use EXIT_SUCCESS and EXIT_FAILURE regardless whether
    the program is compiled to run on some Unix, on some weird mainframe
    with weird exit code values, or in some free-standing implementation
    where there is no OS, not to speak about shell scripts.

    Even on Linux or Windows, note that the exit code numeric values
    contradict the conventions of C and C++ where 1 is normally converted to >>>> true and 0 to false. So to reduce confusion it might be a good idea to >>>> use the macros even here. Note that nowadays there are many programmers >>>> (esp. on Windows) who have no idea about program exit code conventions >>>> or shell scripts.



    EXIT_SUCCESS can be 0xbeefbeef and EXIT_FAILURE can be 0xdeadbeef?


    Not on any POSIX system. EXIT_SUCCESS must be zero. EXIT_FAILURE
    must be between 1 and 125 inclusive.

    https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html


    What about the strict C std, posix aside for a moment?

    I would assume that is entirely up to the implementation. So
    long as the value defined in stdlib.h agrees with the value that
    the rest of the implementation (e.g. powershell/cmd.exe)
    expects.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to wij on Wed Nov 20 23:09:14 2024
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of programs for some reason, but generally, exit code of program is a numerical value. Why EXIT_SUCCESS?

    Because which numeric values qualify as successful and failure codes
    varies from one operating system to another. My own experience includes
    VMS, where even exit codes indicate errors, whereas odd value indicate
    success. Notice that this is incompatible with the POSIX convention of 0
    for success, non-zero for failure. On a VMS system, a conforming version
    of the C standard library must have exit(0) report an odd exit status; EXIT_SUCCESS might be the same odd number, or a different one.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Chris M. Thomasson on Wed Nov 20 23:20:03 2024
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/19/2024 11:22 PM, Paavo Helde wrote:
    On 20.11.2024 05:02, wij wrote:
    ...
    EXIT_SUCCESS can be 0xbeefbeef and EXIT_FAILURE can be 0xdeadbeef?


    Not on any POSIX system. EXIT_SUCCESS must be zero. EXIT_FAILURE
    must be between 1 and 125 inclusive.

    https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html


    What about the strict C std, posix aside for a moment?

    The only requirements are that EXIT_FAILURE and EXIT_SUCCESS must
    "expand to integer constant expressions that can be used as the argument
    to the exit function to return unsuccessful or successful termination
    status, respectively, to the host environment;" (7.24p4) It's completely
    up to the implementation which expressions are used, and there's no
    requirement that there be a direct connection between the value passed
    to exit() and the numeric value received by the host environment. In
    fact, there's no requirement that the status be in the form of an
    integer value.

    A value of 0 passed to exit() must also result in returning a successful termination status to the host environment. EXIT_SUCCESS is not required
    to expand to an integer constant expression with a value of 0, nor is it prohibited from doing so.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From red floyd@21:1/5 to Ross Finlayson on Wed Nov 20 22:56:53 2024
    On 11/20/2024 5:32 PM, Ross Finlayson wrote:

    Thanks that's interesting as sometimes one sees 255.

    I believe that in POSIX, exit codes between 128 to 128 + NSIG inclusive indicate the termination was caused by a signal.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Ross Finlayson on Thu Nov 21 13:51:36 2024
    Ross Finlayson <[email protected]> writes:
    On 11/20/2024 02:11 PM, Scott Lurndal wrote:
    "Chris M. Thomasson" <[email protected]> writes:

    Not on any POSIX system. EXIT_SUCCESS must be zero. EXIT_FAILURE
    must be between 1 and 125 inclusive.

    https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html


    Thanks that's interesting as sometimes one sees 255.

    Any exit value with bit<7> set indicates that the process
    was terminated by a fatal signal (typ. SIGSEGV) and a
    core file was generated on most
    unix and unix-like kernels.

    /* Nonzero if STATUS indicates the child dumped core. */
    #define __WCOREDUMP(status) ((status) & __WCOREFLAG)
    #define __WCOREFLAG 0x80

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to James Kuyper on Thu Nov 21 13:52:58 2024
    James Kuyper <[email protected]> writes:
    On 20.11.2024 05:02, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >> But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of
    programs for some reason, but generally, exit code of program is a numerical >> value. Why EXIT_SUCCESS?

    Because which numeric values qualify as successful and failure codes
    varies from one operating system to another. My own experience includes
    VMS, where even exit codes indicate errors, whereas odd value indicate >success.

    Indeed, and SS$_NORMAL (a success indication) had the value 0x1.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to red floyd on Thu Nov 21 13:52:09 2024
    red floyd <[email protected]d> writes:
    On 11/20/2024 5:32 PM, Ross Finlayson wrote:

    Thanks that's interesting as sometimes one sees 255.

    I believe that in POSIX, exit codes between 128 to 128 + NSIG inclusive >indicate the termination was caused by a signal.

    Acutally bit<7> set indicates that a core file was generated.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Chris M. Thomasson on Thu Nov 21 13:43:30 2024
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:


    Actually, for some reason, this makes me think of nullptr = 0 = NULL wrt
    NULL can be 0xdeadbeefbeefdead?


    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 21 16:07:46 2024
    On Thu, 21 Nov 2024 13:43:30 GMT
    [email protected] (Scott Lurndal) boring babbled:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:


    Actually, for some reason, this makes me think of nullptr = 0 = NULL wrt >>NULL can be 0xdeadbeefbeefdead?


    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    Thats a bit iffy given the number of devs - and I include myself - who often use
    !<whatever> in place of <whatever> == NULL and similarly <whatever> instead
    of <whatever> != NULL.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to [email protected] on Thu Nov 21 17:55:49 2024
    [email protected] writes:
    On Thu, 21 Nov 2024 13:43:30 GMT
    [email protected] (Scott Lurndal) boring babbled:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:


    Actually, for some reason, this makes me think of nullptr = 0 = NULL wrt >>>NULL can be 0xdeadbeefbeefdead?


    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    Thats a bit iffy given the number of devs - and I include myself - who often use
    !<whatever> in place of <whatever> == NULL and similarly <whatever> instead >of <whatever> != NULL.

    No, it's not iffy, that's just bad coding practice on your part.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Scott Lurndal on Fri Nov 22 09:30:45 2024
    On 21/11/2024 18:55, Scott Lurndal wrote:
    [email protected] writes:
    On Thu, 21 Nov 2024 13:43:30 GMT
    [email protected] (Scott Lurndal) boring babbled:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:


    Actually, for some reason, this makes me think of nullptr = 0 = NULL wrt >>>> NULL can be 0xdeadbeefbeefdead?


    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    Thats a bit iffy given the number of devs - and I include myself - who often use
    !<whatever> in place of <whatever> == NULL and similarly <whatever> instead >> of <whatever> != NULL.

    No, it's not iffy, that's just bad coding practice on your part.

    If you are talking about testing a normal pointer to check for a null
    pointer, it is not "iffy" at all in C++. If you have "int * p;", then
    "if (p)" is a conversion of "p" to bool, which is defined as false if
    and only if p is a null pointer. "if (!p)" first converts "p" to bool,
    and then negates it, so it is also entirely well defined.

    For C, "(!p)" is defined as "(0 == p)", which will be true if and only
    if "p" is a null pointer. (An integer constant expression with value 0,
    when converted to a pointer type, is a null pointer constant -
    regardless of representation.)

    All of this applies - AFAICS - regardless of whether the implementation
    uses a bit representation of 0 for a null pointer, or anything else. It
    still applies even if there can be many different representations of
    null pointers, as they must all compare equal.

    However, I can't see a justification for claiming that "if (p)" works as expected for any C implementation. I might be missing something, and of
    course real C implementations will support it as you would expect. In
    C++, "if (p)" converts "p" to bool, but in C, it converts it to "int".
    And while you are guaranteed that converting an integer constant
    expression of value 0 to a pointer type will give you a null pointer,
    you are not guaranteed that a null pointer, converted to an int, will
    give 0. (And int variables and other expressions of int type which
    happen to contain the value 0, are not guaranteed to give null pointers
    when converting to a pointer type - only /constant/ expressions get that treatment.)

    So for C, "if (p)" appears to be "iffy" in theory, but fine in practice.
    "if (!p)" is fine, as is "if (!!p)" and "if ((bool) p)". For C++, "if
    (p)" is solid.

    (If anyone can point to what I am missing that makes "if (p)" safe in C,
    I'd be glad to hear about it.)


    What counts as "bad coding practice" is a much more subjective matter.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Fri Nov 22 09:55:13 2024
    On Thu, 21 Nov 2024 17:55:49 GMT
    [email protected] (Scott Lurndal) boring babbled:
    [email protected] writes:
    On Thu, 21 Nov 2024 13:43:30 GMT
    [email protected] (Scott Lurndal) boring babbled:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:


    Actually, for some reason, this makes me think of nullptr = 0 = NULL wrt >>>>NULL can be 0xdeadbeefbeefdead?


    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    Thats a bit iffy given the number of devs - and I include myself - who often >use
    !<whatever> in place of <whatever> == NULL and similarly <whatever> instead >>of <whatever> != NULL.

    No, it's not iffy, that's just bad coding practice on your part.

    Its entirely standard coding practice.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to [email protected] on Fri Nov 22 11:57:11 2024
    [email protected] writes:
    On Thu, 21 Nov 2024 13:43:30 GMT
    [email protected] (Scott Lurndal) boring babbled:
    ...
    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    Thats a bit iffy given the number of devs - and I include myself - who often use
    !<whatever> in place of <whatever> == NULL and similarly <whatever> instead >of <whatever> != NULL.

    Regardless of a whether null pointers have any bits set, any integer
    constant expression with a value of 0 qualifies as a null pointer
    constant. NULL is required to expand into an NPC, and therefore cannot
    expand into an integer expression with a non-zero value. All such
    expressions must, if they occur in a pointer context, be converted to
    null pointers of the appropriate type.
    Null pointers always compare equal to null pointer constants, because in
    the context of such comparisons, null pointer constants get converted to
    null pointers of the appropriate type, and all null pointers compare equal.

    In every logical context (such as x in if(x), for(...; x; ...),
    while(x), do ... while (x), !x, x1&&x2, x1||x2, x?a:b, etc),pointers are converted to bool, Null pointers converted to bool always result in a
    value of false, regardless o how they are represented.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Scott Lurndal on Fri Nov 22 11:31:00 2024
    On 11/21/24 08:43, Scott Lurndal wrote:
    "Chris M. Thomasson" <[email protected]> writes:
    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:
    On 11/20/2024 2:11 PM, Scott Lurndal wrote:


    Actually, for some reason, this makes me think of nullptr = 0 = NULL wrt
    NULL can be 0xdeadbeefbeefdead?


    I've worked with systems where the NULL pointer value was not zero.

    That's why C has a symbolic constant for NULL.

    Not really - that's the reason why C has special handling for null
    pointer constants. Even on systems where null pointers are represented
    by a bit pattern with one or more bits set, a null pointer constant can
    still be 0, and if used in a pointer context, must be converted to a
    null pointer. The main reason for NULL is that some implementations
    thought it would be better for type safety to use (void*)0.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Keith Thompson on Fri Nov 22 16:53:03 2024
    On 11/22/24 15:36, Keith Thompson wrote:
    James Kuyper <[email protected]> writes:
    ...
    `(void*)0` is a null pointer constant in C but not in C++, because C++
    has no implicit conversion from void* to other pointer types.

    0 is a null pointer constant, and a valid expansion for NULL, in both C
    and C++.

    Note that `(void*)0` is a C null pointer constant, but not a valid
    expansion for NULL. It needs to be `((void*)0)`. (A painfully literal reading of the C standard up to and including C17 suggests that a parenthesized null pointer constant is not a null pointer constant, but
    C23 corrects that oversight.)

    In my opinion, the main reason for NULL is that it lets the programmer explicitly state that it's a null pointer constant and not just zero.
    (But NULL can still be of type int.) I find nullptr (in C++ and C23) an improvement over NULL.

    I started writing that response thinking that this thread was on
    comp.lang.c. Then I noticed this was comp.lang.c++, and made a few
    corrections, but not as many as I should have.
    I strongly agree - nullptr in C++ is what NULL should always have been,
    but it took a couple of decade's experi9ence with C and C++ to figure
    out the right way to do it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Keith Thompson on Fri Nov 22 23:26:03 2024
    Keith Thompson <[email protected]> writes:
    David Brown <[email protected]> writes:
    [...]

    >>Scott Lurndal argued that testing for a null pointer using if (!pointer)
    >> is iffy and poor coding practice.

    What counts as "bad coding practice" is a much more subjective matter.

    Indeed. I would write `if (foo)` only if foo is of type bool/_Bool (or
    is "logically Boolean", such as a C int value with no meaninful
    distinction among non-zero values). I would write:

    - `if (foo != NULL)` or `if (foo != nullptr)` for a pointer;
    - `if (foo != '\0')` for a character (or '\0L');
    - `if (foo != 0)` for an integer that doesn't denote a character or
    boolean value (or possibly `0L` et al);
    - `if (foo != 0.0)` for a floating-point value (or possibly
    0.0f or 0.0L).

    I've also followed these guidelines since I started programming in
    C and later C++ some forty years ago. It seems natural to me at
    this point. I recognize that other programmers prefer the more
    abbreviated form.


    But that's my own preference, and I don't have any problem reading code >written by people with different preferences. I recognize that more >agressive use of `if (foo)` is a common idiom, one I'll follow myself if
    I'm subjected to a coding standard that requires it.

    Indeed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Sat Nov 23 11:36:45 2024
    On Fri, 22 Nov 2024 11:10:57 -0800
    Ross Finlayson <[email protected]> gabbled:
    (Reminds of "if (!!p)" Otherwise that NULL is usually declared (void*)0

    Thats actually a very convenient way to convert any -N -> 0 -> N value into
    0 or 1. I've used it myself a couple of times.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Keith Thompson on Sat Nov 23 13:07:26 2024
    On 22/11/2024 21:26, Keith Thompson wrote:
    David Brown <[email protected]> writes:
    [...]
    However, I can't see a justification for claiming that "if (p)" works
    as expected for any C implementation. I might be missing something,
    and of course real C implementations will support it as you would
    expect. In C++, "if (p)" converts "p" to bool, but in C, it converts
    it to "int". And while you are guaranteed that converting an integer
    constant expression of value 0 to a pointer type will give you a null
    pointer, you are not guaranteed that a null pointer, converted to an
    int, will give 0. (And int variables and other expressions of int
    type which happen to contain the value 0, are not guaranteed to give
    null pointers when converting to a pointer type - only /constant/
    expressions get that treatment.)

    Yes, you're missing something.

    some_type *p;
    if (p) do_something();

    N1570 6.8.4: `do_something();` is executed if p "compares unequal to 0",
    so `if (p)` is equivalent to `if (p != 0)`.


    Ah, yes - thanks!

    N1570 6.5.10: "If one operand is a pointer and the other is a null
    pointer constant, the null pointer constant is converted to the type of
    the pointer." 0 is a null pointer constant, so it's converted to type `some_type*`, yielding a null pointer value of that type.

    In `if (p)`, p is not converted to int. It's compared for inequality to
    0, and the result of that comparison is of type int.


    That is interesting - I had been assuming the controlling expression of
    "if" was converted to type "int" in C, in the way that it is converted
    to "bool" in C++. I guess I should not have been making assumptions!



    So for C, "if (p)" appears to be "iffy" in theory, but fine in
    practice. "if (!p)" is fine, as is "if (!!p)" and "if ((bool) p)".
    For C++, "if (p)" is solid.

    (If anyone can point to what I am missing that makes "if (p)" safe in
    C, I'd be glad to hear about it.)

    What counts as "bad coding practice" is a much more subjective matter.

    Indeed. I would write `if (foo)` only if foo is of type bool/_Bool (or
    is "logically Boolean", such as a C int value with no meaninful
    distinction among non-zero values). I would write:

    - `if (foo != NULL)` or `if (foo != nullptr)` for a pointer;
    - `if (foo != '\0')` for a character (or '\0L');
    - `if (foo != 0)` for an integer that doesn't denote a character or
    boolean value (or possibly `0L` et al);
    - `if (foo != 0.0)` for a floating-point value (or possibly
    0.0f or 0.0L).

    But that's my own preference, and I don't have any problem reading code written by people with different preferences. I recognize that more agressive use of `if (foo)` is a common idiom, one I'll follow myself if
    I'm subjected to a coding standard that requires it.


    I am quite happy to write "if (p) ... " for checking a pointer - but I
    would write the code and name variables in a way that makes it entirely
    clear that "p" is a pointer. Code clarity is the main point. (I am
    also happy to check my std::optional<> variables with "if (xp) ..."
    style checks.)

    I don't like to use 0 for a null pointer constant, either for setting or
    for comparison - I'm glad to see nullptr has made it into C as well as C++.

    But to my mind, "if (p)" is asking "Is p a pointer to something?", while
    "if (p != nullptr)" is asking "Is p not equal to nullptr?". The first
    version seems a more accurate representation of what I actually want,
    while the second is somewhat indirect. I am testing a characteristic of
    the expression, rather than trying to see what it is not.

    I don't know if there are any real-world implementations (of C or C++)
    with more than one representation for null pointers, but null pointers
    are somewhat special. "if (x == y)" compares for equality of two
    values, unless one of these is a pointer and the other is a null pointer constant - then the comparison is more of a classification, checking if
    the pointer is in the set of null pointer values.

    Once you move beyond just C-style pointers, testing by contextual
    conversion to bool becomes a lot more versatile than comparing against a specific "magic" value. I would check std::unique_ptr<> values with "if
    (p)" rather than "if (p.get() != nullptr)", and std::expected<> with "if
    (x)" rather than "if (x.has_value())".


    Of course I am happy to read code using either convention, and
    consistency of style is probably more important than either choice.
    Whatever makes the meaning of the code clearest, and reduces the risk of mistakes or misunderstandings, is the best choice.


    (C tends to use int for character and Boolean values. C++ tends not to
    do that as much, though you can still write C-style code in C++, and C++ includes (most of) the C standard library.)

    I didn't cross-post this to comp.lang.c, but we might consider doing so
    if the discussion continues into C-specific content.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rosario19@21:1/5 to wij on Mon Nov 25 22:20:55 2024
    On Wed, 20 Nov 2024 11:02:49 +0800, wij <[email protected]> wrote:

    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of >programs for some reason, but generally, exit code of program is a numerical >value. Why EXIT_SUCCESS?

    because the success is one only case
    and failure can happen for 10000000 of causes differents
    the success has to be one number
    and failure all the remain numbers
    as example 0 success -inf .. +inf -{0} failure

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Fred. Zwarts@21:1/5 to All on Tue Nov 26 10:20:07 2024
    Op 25.nov.2024 om 22:20 schreef Rosario19:
    On Wed, 20 Nov 2024 11:02:49 +0800, wij <[email protected]> wrote:

    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >> But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of
    programs for some reason, but generally, exit code of program is a numerical >> value. Why EXIT_SUCCESS?

    because the success is one only case
    and failure can happen for 10000000 of causes differents
    the success has to be one number
    and failure all the remain numbers
    as example 0 success -inf .. +inf -{0} failure

    In some situations there can be different success cases, as well.
    E.g. when searching for something, both finding something and finding
    nothing is a valuable result and not a failure of the search operation.
    It is worthwhile to indicate them with different success codes.
    That can be done in VMS where odd codes are all success codes.
    One could also think of a success code that includes the number of
    results. (That is what many I/O functions do: A positive value indicates
    a success with the number of bytes transferred, a negative number
    indicates a failure.)
    Failures are a different thing; they make the result of the operation
    invalid. They should be indicated with an error code.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Scott Lurndal on Tue Nov 26 04:21:02 2024
    [email protected] (Scott Lurndal) writes:

    [email protected] writes:

    On Thu, 21 Nov 2024 13:43:30 GMT
    [email protected] (Scott Lurndal) boring babbled:

    "Chris M. Thomasson" <[email protected]> writes:

    On 11/20/2024 2:33 PM, Chris M. Thomasson wrote:

    On 11/20/2024 2:11 PM, Scott Lurndal wrote:

    Actually, for some reason, this makes me think of nullptr = 0 =
    NULL wrt NULL can be 0xdeadbeefbeefdead?

    I've worked with systems where the NULL pointer value was not
    zero.

    That's why C has a symbolic constant for NULL.

    Thats a bit iffy given the number of devs - and I include myself -
    who often use !<whatever> in place of <whatever> == NULL and
    similarly <whatever> instead of <whatever> != NULL.

    No, it's not iffy, that's just bad coding practice on your part.

    That is a commonly held view, but I've never seen any defense
    offered for it other than folklore.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to James Kuyper on Tue Nov 26 04:26:13 2024
    James Kuyper <[email protected]> writes:

    [...] The main reason for NULL is that some implementations
    thought it would be better for type safety to use (void*)0.

    The problem with that theory is NULL predates both C++ and also
    any introduction of void or the void* type.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 27 08:26:12 2024
    On Wed, 27 Nov 2024 16:23:55 +0800
    wij <[email protected]> boring babbled:
    On Tue, 2024-11-26 at 12:21 +0800, wij wrote:
    looks bad, but it works fine. Any way, inventing nullptr for such rare? c= >ase
    is IOM overkill.

    I think now, inventing nullptr is a practical step of evolution. So, in the >future, expansion of NULL might be nullptr. ... NULL will still be valid fo= >r=C2=A0
    a long time, both in C and C++.

    Stop replying to your own nonsense with yet more nonsense. No one cares.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to wij on Wed Nov 27 15:39:51 2024
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if ::fopen(..) failed? NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not work
    reliably with Unicode characters in Windows paths. One needs to use some
    kind of helper library for having portable code. In principle std::filesystem::path ought to work, but I have no experience with it.

    About null pointers: in C++ it is spelled `nullptr`.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to [email protected] on Wed Nov 27 15:30:58 2024
    On Wed, 27 Nov 2024 08:26:12 -0000 (UTC)
    [email protected] wrote:

    On Wed, 27 Nov 2024 16:23:55 +0800
    wij <[email protected]> boring babbled:
    On Tue, 2024-11-26 at 12:21 +0800, wij wrote:
    looks bad, but it works fine. Any way, inventing nullptr for such
    rare? c=
    ase
    is IOM overkill.

    I think now, inventing nullptr is a practical step of evolution. So,
    in the future, expansion of NULL might be nullptr. ... NULL will
    still be valid fo= r=C2=A0
    a long time, both in C and C++.

    Stop replying to your own nonsense with yet more nonsense. No one
    cares.


    Nothing particularly wrong in replying to own posts, nonsense or not.
    Esp. so when the thread was started by yourself.

    What *is* wrong and annoying is starting lots of nonsense short threads.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 27 13:52:46 2024
    On Wed, 27 Nov 2024 18:48:13 +0800
    wij <[email protected]> wibbled:
    On Wed, 2024-11-27 at 08:26 +0000, [email protected] wrote:
    On Wed, 27 Nov 2024 16:23:55 +0800
    wij <[email protected]> boring babbled:
    On Tue, 2024-11-26 at 12:21 +0800, wij wrote:
    looks bad, but it works fine. Any way, inventing nullptr for such rar= >e? c=3D
    ase
    is IOM overkill.
    =20
    I think now, inventing nullptr is a practical step of evolution. So, in=
    the
    future, expansion of NULL might be nullptr. ... NULL will still be vali= >d fo=3D
    r=3DC2=3DA0
    a long time, both in C and C++.
    =20
    Stop replying to your own nonsense with yet more nonsense. No one cares.

    It was a correction of my previous post. Not every post is for you.

    Not sure yours are for anyone except yourself.

    If you feel sth have to utter, utter sth on topic. We know you are not ther= >e, but
    we won't laught.

    You could translate that into comprehensible english?

    A clue for you: What should be in a 'portabe' program if ::fopen(..) failed= >? NULL=C2=A0
    or nullptr? What about "if(::fopen(..)"?

    Any chance you could stop your newsreader randomly using QP encoding for 7 bit ascii characters?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 27 13:54:04 2024
    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if ::fopen(..) failed? >NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not work >reliably with Unicode characters in Windows paths. One needs to use some
    kind of helper library for having portable code. In principle >std::filesystem::path ought to work, but I have no experience with it.

    So how does file access work in plain C in Windows then? I'm pretty sure fopen() works fine given its a core C API function.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to [email protected] on Wed Nov 27 17:24:05 2024
    On Wed, 27 Nov 2024 13:54:04 -0000 (UTC)
    [email protected] wrote:

    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if
    ::fopen(..) failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not
    work reliably with Unicode characters in Windows paths. One needs to
    use some kind of helper library for having portable code. In
    principle std::filesystem::path ought to work, but I have no
    experience with it.

    So how does file access work in plain C in Windows then? I'm pretty
    sure fopen() works fine given its a core C API function.


    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows, happen
    to be 2nd class. The biggest problem with ASCII paths on Windows is
    that they are limited to 256 characters. Or to 512 characters if you
    turn on some obscure registry keys. In practice, 256 characters quite
    often is too short.

    Even big SW vendors sometimes fall in this trap. One example I
    encountered recently is Xilinx (now owned by AMD).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 27 16:12:40 2024
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    On Wed, 27 Nov 2024 13:54:04 -0000 (UTC)
    [email protected] wrote:

    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if
    ::fopen(..) failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not
    work reliably with Unicode characters in Windows paths. One needs to
    use some kind of helper library for having portable code. In
    principle std::filesystem::path ought to work, but I have no
    experience with it.

    So how does file access work in plain C in Windows then? I'm pretty
    sure fopen() works fine given its a core C API function.


    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows, happen
    to be 2nd class. The biggest problem with ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to [email protected] on Wed Nov 27 19:01:06 2024
    On 27.11.2024 15:54, [email protected] wrote:
    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if ::fopen(..) failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not work
    reliably with Unicode characters in Windows paths. One needs to use some
    kind of helper library for having portable code. In principle
    std::filesystem::path ought to work, but I have no experience with it.

    So how does file access work in plain C in Windows then? I'm pretty sure fopen() works fine given its a core C API function.

    In C one can use _wfopen() or _wfopen_s() in Windows. As you can guess
    these are pretty non-portable.

    The libraries which provide their own file opening functions typically
    provide the wide char variants as well, specifially for supporting
    Windows. For example, libTIFF provides TIFFOpenW() and zlib provides gzopen_w().

    In a better world MS should implement full support for the UTF-8 locale
    and deprecate all other locales, making all this wide char stuff
    unneeded. Not sure how far they are on this (IMO unevitable) path. In an
    ideal world they would have done that already 15 years ago.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to [email protected] on Wed Nov 27 13:00:17 2024
    On 11/27/24 11:12 AM, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    On Wed, 27 Nov 2024 13:54:04 -0000 (UTC)
    [email protected] wrote:

    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if
    ::fopen(..) failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not
    work reliably with Unicode characters in Windows paths. One needs to
    use some kind of helper library for having portable code. In
    principle std::filesystem::path ought to work, but I have no
    experience with it.

    So how does file access work in plain C in Windows then? I'm pretty
    sure fopen() works fine given its a core C API function.


    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows, happen
    to be 2nd class. The biggest problem with ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?



    Because the windows file system is based on UTF-16 file names?

    The UTF-8 interface is just more limited.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Paavo Helde on Wed Nov 27 14:57:38 2024
    On 11/27/24 08:39, Paavo Helde wrote:
    ...
    About null pointers: in C++ it is spelled `nullptr`.

    No, in C++, using nullptr is one way to get a null pointer. It is not,
    however, the only way:

    "A null pointer constant is an integral constant expression (5.19)
    rvalue of integer type that evaluates to zero or an rvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer
    type; the result is the null pointer value of that type..." (4.10p1).

    Note that nullptr is an rvalue of type std::nullptr_t, but other things
    can also have that type. Also, null pointers can be created by
    conversion from null pointer constants, but they can also be generated
    by other means.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to [email protected] on Wed Nov 27 14:54:00 2024
    On 11/27/24 08:52, [email protected] wrote:
    On Wed, 27 Nov 2024 18:48:13 +0800
    wij <[email protected]> wibbled:
    ...
    If you feel sth have to utter, utter sth on topic. We know you are not ther= >> e, but
    we won't laught.

    You could translate that into comprehensible english?

    Of course he can't - he's wij. Comprehensibility is not an available
    option for him.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to [email protected] on Wed Nov 27 14:58:18 2024
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ...
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows, happen
    to be 2nd class. The biggest problem with ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what makes
    them 2nd class.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 28 08:22:35 2024
    On Wed, 27 Nov 2024 19:01:06 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 15:54, [email protected] wrote:
    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if ::fopen(..) >failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not work
    reliably with Unicode characters in Windows paths. One needs to use some >>> kind of helper library for having portable code. In principle
    std::filesystem::path ought to work, but I have no experience with it.

    So how does file access work in plain C in Windows then? I'm pretty sure
    fopen() works fine given its a core C API function.

    In C one can use _wfopen() or _wfopen_s() in Windows. As you can guess
    these are pretty non-portable.

    The libraries which provide their own file opening functions typically >provide the wide char variants as well, specifially for supporting
    Windows. For example, libTIFF provides TIFFOpenW() and zlib provides >gzopen_w().

    In a better world MS should implement full support for the UTF-8 locale
    and deprecate all other locales, making all this wide char stuff
    unneeded. Not sure how far they are on this (IMO unevitable) path. In an >ideal world they would have done that already 15 years ago.

    What a mess. The unix approach whereby a filename is simply a sequence of
    bytes (except for \0 but I'm not 100% sure) seems a lot more sensible.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 28 08:23:55 2024
    On Wed, 27 Nov 2024 13:00:17 -0500
    Richard Damon <[email protected]> wibbled:
    On 11/27/24 11:12 AM, [email protected] wrote:
    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?



    Because the windows file system is based on UTF-16 file names?

    Oh. Its always nice to have yet more reasons never to go near Windows development again.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 28 08:26:02 2024
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ....
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows, happen
    to be 2nd class. The biggest problem with ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what makes
    them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii 2nd class.
    The only issue comes when some idiot tries to mix utf-8 with 8 bit ascii
    code pages.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Thu Nov 28 12:15:21 2024
    * Paavo Helde <[email protected]>
    | On 28.11.2024 10:26, [email protected] wrote:
    | > On Wed, 27 Nov 2024 14:58:18 -0500
    | > James Kuyper <[email protected]> wibbled:
    | >> On 11/27/24 11:12, [email protected] wrote:
    | >>> On Wed, 27 Nov 2024 17:24:05 +0200
    | >>> Michael S <[email protected]> wibbled:
    | >> ....
    | >>>> It works, but badly rather than fine.
    | >>>> Specifically, it works only with ASCII paths. Which, on Windows, happen | >>>> to be 2nd class. The biggest problem with ASCII paths on Windows is --<snip-snip>--

    | Though this is changing now, I just ran a quick test and apparently
    | calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with
    | VS2022 on Windows 10 and I can pass UTF-8 filenames to narrow-string
    | fopen() and they work properly. So there is progress!

    Does fopen() also work with filenames where the UTF-8 is not part of
    your et_EE.UTF-8 codepage (e.g. filenames containing japanese
    characters)? I think that with these only the _wfopen() will work...

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to [email protected] on Thu Nov 28 13:03:20 2024
    On 28.11.2024 10:26, [email protected] wrote:
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ....
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows, happen >>>> to be 2nd class. The biggest problem with ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what makes
    them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii 2nd class.
    The only issue comes when some idiot tries to mix utf-8 with 8 bit ascii
    code pages.

    You are right, ASCII is not 2nd class because it is part of UTF-8. It is
    2nd class on Windows because MS have historically decided to not support
    UTF-8 properly on Windows, in an attempt of a futile vendor lock-in.

    Though this is changing now, I just ran a quick test and apparently
    calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with VS2022
    on Windows 10 and I can pass UTF-8 filenames to narrow-string fopen()
    and they work properly. So there is progress!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to Ralf Fassel on Thu Nov 28 13:36:36 2024
    On 28.11.2024 13:15, Ralf Fassel wrote:
    * Paavo Helde <[email protected]>
    | On 28.11.2024 10:26, [email protected] wrote:
    | > On Wed, 27 Nov 2024 14:58:18 -0500
    | > James Kuyper <[email protected]> wibbled:
    | >> On 11/27/24 11:12, [email protected] wrote:
    | >>> On Wed, 27 Nov 2024 17:24:05 +0200
    | >>> Michael S <[email protected]> wibbled:
    | >> ....
    | >>>> It works, but badly rather than fine.
    | >>>> Specifically, it works only with ASCII paths. Which, on Windows, happen
    | >>>> to be 2nd class. The biggest problem with ASCII paths on Windows is --<snip-snip>--

    | Though this is changing now, I just ran a quick test and apparently
    | calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with
    | VS2022 on Windows 10 and I can pass UTF-8 filenames to narrow-string
    | fopen() and they work properly. So there is progress!

    Does fopen() also work with filenames where the UTF-8 is not part of
    your et_EE.UTF-8 codepage (e.g. filenames containing japanese
    characters)? I think that with these only the _wfopen() will work...

    Any UTF-8 locale should support all UTF-8 characters, so it should not
    matter what I write before that. But I can test the Japanese characters
    easily, this is an example testing "CJK Unified Ideograph-6F22" (https://www.compart.com/en/unicode/U+6F22).

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <string>
    int main() {
    char* loc = setlocale(LC_ALL, "et_EE.UTF-8");
    if (!loc) {
    std::cerr << "Failed to set locale" << std::endl;
    }
    std::string filename = "C:\\Tmp\\Japan\xE6\xBC\xA2.txt";
    if (FILE* f = ::fopen(filename.c_str(), "w")) {
    std::cout << "File opened" << std::endl;
    fprintf(f, "This is file: %s\n", filename.c_str());
    ::fclose(f);
    } else {
    std::cerr << "Failed to open file" << std::endl;
    }
    }

    The file is created fine, what I see in File Explorer: Japan漢.txt

    The content of the file is OK as well, but this is less surprising.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Michael S on Thu Nov 28 08:08:25 2024
    On 11/28/24 8:06 AM, Michael S wrote:
    On Wed, 27 Nov 2024 13:00:17 -0500
    Richard Damon <[email protected]> wrote:

    On 11/27/24 11:12 AM, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    On Wed, 27 Nov 2024 13:54:04 -0000 (UTC)
    [email protected] wrote:

    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if
    ::fopen(..) failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not
    work reliably with Unicode characters in Windows paths. One
    needs to use some kind of helper library for having portable
    code. In principle std::filesystem::path ought to work, but I
    have no experience with it.

    So how does file access work in plain C in Windows then? I'm
    pretty sure fopen() works fine given its a core C API function.


    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows,
    happen to be 2nd class. The biggest problem with ASCII paths on
    Windows is

    How can ascii paths be 2nd class (whatever that means) given that
    ascii is a subset of utf-8?



    Because the windows file system is based on UTF-16 file names?

    The UTF-8 interface is just more limited.

    Actually, I can not think about good reason for 260-char limit of
    maximal path length in ASCII variant of Windows files APIs.
    It's probably somehow related to compatibility with Wn16, but I don't
    see how exactly.

    I am also not sure that [for names started with "\\?\" prefix] the
    limit still present in the newer editions of the OS. Up to date docs
    are less clear about it than the older docs that I seems to recollect.
    Most of the docs are written as if longer paths should work in ASCII.
    But in one place there is the following line "Note that Unicode APIs
    should be used to make sure the "\\?\" prefix allows you to exceed the MAX_PATH." https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file

    This line seems to contradict the following page: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea

    Unfortunately, right now I have no time for deeper investigation.


    My guess is that at some point the code needs to convert the 8 bit
    character encoding into the 16 character encoding that the actual file
    system uses, and that uses fixed length buffers.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Paavo Helde on Thu Nov 28 07:50:04 2024
    On 11/28/24 6:03 AM, Paavo Helde wrote:
    On 28.11.2024 10:26, [email protected] wrote:
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ....
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows,
    happen
    to be 2nd class. The biggest problem with ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given that ascii >>>> is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what makes
    them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii 2nd class.
    The only issue comes when some idiot tries to mix utf-8 with 8 bit ascii
    code pages.

    You are right, ASCII is not 2nd class because it is part of UTF-8. It is
    2nd class on Windows because MS have historically decided to not support UTF-8 properly on Windows, in an attempt of a futile vendor lock-in.

    Though this is changing now, I just ran a quick test and apparently
    calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with VS2022
    on Windows 10 and I can pass UTF-8 filenames to narrow-string fopen()
    and they work properly. So there is progress!



    To be fair to Microsoft, what happened was less devious, they decided
    that the answer to global operation was to just store filename in the
    universal coding of the time, UCS-2, which was supposed to handle every character in the world.

    The problem with being an early adopter of that standard, was that the
    Unicode Consortium realized there weren't enough code points in UCS-2,
    so Unicode expanded to more bits, 21 being what could be simply encoded
    into UTF-16, what UCS-2 would morph into.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Richard Damon on Thu Nov 28 15:06:01 2024
    On Wed, 27 Nov 2024 13:00:17 -0500
    Richard Damon <[email protected]> wrote:

    On 11/27/24 11:12 AM, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    On Wed, 27 Nov 2024 13:54:04 -0000 (UTC)
    [email protected] wrote:

    On Wed, 27 Nov 2024 15:39:51 +0200
    Paavo Helde <[email protected]> wibbled:
    On 27.11.2024 12:48, wij wrote:

    A clue for you: What should be in a 'portabe' program if
    ::fopen(..) failed?
    NULL
    or nullptr? What about "if(::fopen(..)"?

    In a portable program one cannot just use fopen() as it does not
    work reliably with Unicode characters in Windows paths. One
    needs to use some kind of helper library for having portable
    code. In principle std::filesystem::path ought to work, but I
    have no experience with it.

    So how does file access work in plain C in Windows then? I'm
    pretty sure fopen() works fine given its a core C API function.


    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows,
    happen to be 2nd class. The biggest problem with ASCII paths on
    Windows is

    How can ascii paths be 2nd class (whatever that means) given that
    ascii is a subset of utf-8?



    Because the windows file system is based on UTF-16 file names?

    The UTF-8 interface is just more limited.

    Actually, I can not think about good reason for 260-char limit of
    maximal path length in ASCII variant of Windows files APIs.
    It's probably somehow related to compatibility with Wn16, but I don't
    see how exactly.

    I am also not sure that [for names started with "\\?\" prefix] the
    limit still present in the newer editions of the OS. Up to date docs
    are less clear about it than the older docs that I seems to recollect.
    Most of the docs are written as if longer paths should work in ASCII.
    But in one place there is the following line "Note that Unicode APIs
    should be used to make sure the "\\?\" prefix allows you to exceed the MAX_PATH."
    https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file

    This line seems to contradict the following page: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea

    Unfortunately, right now I have no time for deeper investigation.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Thu Nov 28 14:12:17 2024
    * Paavo Helde <[email protected]>
    | Any UTF-8 locale should support all UTF-8 characters, so it should not
    | matter what I write before that. But I can test the Japanese
    | characters
    | easily, this is an example testing "CJK Unified Ideograph-6F22"
    | (https://www.compart.com/en/unicode/U+6F22).

    | #define _CRT_SECURE_NO_WARNINGS
    | #include <iostream>
    | #include <string>
    | int main() {
    | char* loc = setlocale(LC_ALL, "et_EE.UTF-8");
    | if (!loc) {
    | std::cerr << "Failed to set locale" << std::endl;
    | }
    | std::string filename = "C:\\Tmp\\Japan\xE6\xBC\xA2.txt";
    | if (FILE* f = ::fopen(filename.c_str(), "w")) {
    | std::cout << "File opened" << std::endl;
    | fprintf(f, "This is file: %s\n", filename.c_str());
    | ::fclose(f);
    | } else {
    | std::cerr << "Failed to open file" << std::endl;
    | }
    | }

    | The file is created fine, what I see in File Explorer: Japan漢.txt

    | The content of the file is OK as well, but this is less surprising.

    Great, thanks for the clarification (though of course waaaay off-topic
    in the meantime :-)!

    https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-170

    section "UTF-8 support" also confirms it:

    After calling setlocale(LC_ALL, ".UTF8"), you may pass "😊" to
    mbtowcs and it will be properly translated to a wchar_t
    string. Previously, there wasn't a locale setting available to do
    this translation.

    Starting in Windows 10 version 1803 (10.0.17134.0), the Universal C
    Runtime supports using a UTF-8 code page. The change means that char
    strings passed to C runtime functions can expect strings in the
    UTF-8 encoding.
    --<snip-snip>--
    UTF-8 mode is also enabled for functions that have historically
    translated char strings using the default Windows ANSI code page
    (ACP). For example, calling _mkdir("😊") while using a UTF-8 code
    page will correctly produce a directory with that emoji as the
    folder name, instead of requiring the ACP to be changed to UTF-8
    before running your program.

    The other end of the problem is how these filenames enter your program
    through main(int argc, char *argv[]). If you start in a regular cmd.exe
    with a regular windows code page (no utf-8 magic), you get "Japan?.txt"
    for the above file name. Only in _wmain(int argc, wchar_t *argv[]) you
    get the correct filename. Haven't played with chcp 65001 (=utf-8) yet...

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to James Kuyper on Thu Nov 28 15:27:50 2024
    On Wed, 27 Nov 2024 14:54:00 -0500
    James Kuyper <[email protected]> wrote:

    On 11/27/24 08:52, [email protected] wrote:
    On Wed, 27 Nov 2024 18:48:13 +0800
    wij <[email protected]> wibbled:
    ...
    If you feel sth have to utter, utter sth on topic. We know you are
    not ther= e, but
    we won't laught.

    You could translate that into comprehensible english?

    Of course he can't - he's wij. Comprehensibility is not an available
    option for him.


    Do you realize that your reply can be interpreted as that you
    sympathies Muttley's rude attempt of policing wij ?
    I hope that it was not your intention.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Paavo Helde on Thu Nov 28 15:19:43 2024
    On Thu, 28 Nov 2024 13:03:20 +0200
    Paavo Helde <[email protected]> wrote:

    On 28.11.2024 10:26, [email protected] wrote:
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ....
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on Windows,
    happen to be 2nd class. The biggest problem with ASCII paths on
    Windows is

    How can ascii paths be 2nd class (whatever that means) given that
    ascii is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what
    makes them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii 2nd
    class. The only issue comes when some idiot tries to mix utf-8 with
    8 bit ascii code pages.

    You are right, ASCII is not 2nd class because it is part of UTF-8. It
    is 2nd class on Windows because MS have historically decided to not
    support UTF-8 properly on Windows, in an attempt of a futile vendor
    lock-in.


    Not sure that it was about lock in. At time Win32 was conceived, UTF8
    didn't exist. At time WinNt was shipped, it still was less than a
    year old. Back then choosing UTF16 looked reasonable.
    Up to ~15 years ago it was not clear that UTF8 not just won, but won decisively, so siting on the fence, waiting for the outcome of the
    battle and rooting for legacy was not totally unreasonable. For what
    happened after that, you could not underestimated a factor of laziness.

    Though this is changing now, I just ran a quick test and apparently
    calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with
    VS2022 on Windows 10 and I can pass UTF-8 filenames to narrow-string
    fopen() and they work properly. So there is progress!


    Can you try it with paths that are longer than 260 characters? Both
    prefixed with "\\?\" and non-prefixed?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 28 15:12:50 2024
    On Thu, 28 Nov 2024 15:19:43 +0200
    Michael S <[email protected]> wibbled:
    Not sure that it was about lock in. At time Win32 was conceived, UTF8
    didn't exist. At time WinNt was shipped, it still was less than a
    year old. Back then choosing UTF16 looked reasonable.
    Up to ~15 years ago it was not clear that UTF8 not just won, but won >decisively, so siting on the fence, waiting for the outcome of the
    battle and rooting for legacy was not totally unreasonable. For what
    happened after that, you could not underestimated a factor of laziness.

    Though this is changing now, I just ran a quick test and apparently
    calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with
    VS2022 on Windows 10 and I can pass UTF-8 filenames to narrow-string
    fopen() and they work properly. So there is progress!


    Can you try it with paths that are longer than 260 characters? Both
    prefixed with "\\?\" and non-prefixed?

    Of course if MS had simply treated filenames as a sequence of 8 bit bytes regardless of what they did or didn't encode - as per *nix - then all this nonsense could have been avoided. It would simply have been left to the
    "dir" command or Explorer to decode it appropriately.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to [email protected] on Thu Nov 28 17:36:29 2024
    On Thu, 28 Nov 2024 15:12:50 -0000 (UTC)
    [email protected] wrote:

    Of course if MS had simply treated filenames as a sequence of 8 bit
    bytes regardless of what they did or didn't encode - as per *nix -
    then all this nonsense could have been avoided. It would simply have
    been left to the "dir" command or Explorer to decode it appropriately.


    It's not that simple. The OS still has to properly recognize backslash
    as a directory separators. In case of Windows, colon also has a special meaning. And in most APIs backslash can be substituted by forward
    slash. So, counting '\0' as well, you have at least four special
    characters dependent on encoding. May be, there are more, that I don't remember.
    Simplicity of handling of file names in Unices is greatly helped by
    UTF-8 encoding they had chosen. They were lucky being late adapters of
    the Unicode. OTOH, UTF-8 didn't exist yet when most of Win32 definitions
    took place (supposedly 1990-1991).

    Of course none of the said above justifies MS's hard limiting of ASCII
    file paths to 260 characters. That is, if limits are still there. May
    be, they are lifted when I didn't pay attention.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 28 15:59:04 2024
    On Thu, 28 Nov 2024 16:43:00 +0100
    David Brown <[email protected]> wibbled:
    On 28/11/2024 16:12, [email protected] wrote:
    handling systems. All this was perfectly reasonable for a small
    single-user single-tasking OS on limited hardware, and more efficient on
    the PC than the Unix system would have been.

    Sure, no argument there, but once NTFS came along they should really have sorted things out. There could have been a backwards compat mode in order to present a single rooted file system as a multi rooted one for older apps and convert filenames etc.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to [email protected] on Thu Nov 28 16:43:00 2024
    On 28/11/2024 16:12, [email protected] wrote:
    On Thu, 28 Nov 2024 15:19:43 +0200
    Michael S <[email protected]> wibbled:
    Not sure that it was about lock in. At time Win32 was conceived, UTF8
    didn't exist. At time WinNt was shipped, it still was less than a
    year old. Back then choosing UTF16 looked reasonable.
    Up to ~15 years ago it was not clear that UTF8 not just won, but won
    decisively, so siting on the fence, waiting for the outcome of the
    battle and rooting for legacy was not totally unreasonable. For what
    happened after that, you could not underestimated a factor of laziness.

    Though this is changing now, I just ran a quick test and apparently
    calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with
    VS2022 on Windows 10 and I can pass UTF-8 filenames to narrow-string
    fopen() and they work properly. So there is progress!


    Can you try it with paths that are longer than 260 characters? Both
    prefixed with "\\?\" and non-prefixed?

    Of course if MS had simply treated filenames as a sequence of 8 bit bytes regardless of what they did or didn't encode - as per *nix - then all this nonsense could have been avoided. It would simply have been left to the
    "dir" command or Explorer to decode it appropriately.


    Sure.

    But they were hindered by backwards compatibility, going back to early
    MSDOS days.

    Early Unix made the decision that it was not going to care about
    filenames, except for a NUL character terminator and the forward slash character. Special files (devices, pipes, etc.) would be indicated by information stored in the file system. Different filesystems could be
    mounted all within the same root system.

    Early MSDOS made the decision that a filesystem was for storing files
    and directories, and device drivers would be something different.
    Different filesystems would have drive letters. This made the
    filesystems noticeably simpler, made it clear to users when files were
    on diskettes, harddrives, network drivers, etc. To help compatibility
    and porting, they made a few specific device drivers available via
    specially named files, which were handled as exceptions in the file
    handling systems. All this was perfectly reasonable for a small
    single-user single-tasking OS on limited hardware, and more efficient on
    the PC than the Unix system would have been.

    Fast-forward to today, and it's easy to see that the Unix philosophy
    here turned out to be far better for the hardware we have now. But MS's decisions were not bad choices at the time they were made. Just like
    the use of UCS2, it was not about lock-in or incompetence, it was a
    failure to think far enough ahead while being hindered by backwards compatibility.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to All on Thu Nov 28 22:41:42 2024
    T24gMjguMTEuMjAyNCAxNToxOSwgTWljaGFlbCBTIHdyb3RlOg0KPiBPbiBUaHUsIDI4IE5v diAyMDI0IDEzOjAzOjIwICswMjAwDQo+IFBhYXZvIEhlbGRlIDxlZXNuaW1pQG9zYS5wcmku ZWU+IHdyb3RlOg0KPiANCj4+IE9uIDI4LjExLjIwMjQgMTA6MjYsIE11dHRsZXlARGFzdGFy ZGx5SFEub3JnIHdyb3RlOg0KPj4+IE9uIFdlZCwgMjcgTm92IDIwMjQgMTQ6NTg6MTggLTA1 MDANCj4+PiBKYW1lcyBLdXlwZXIgPGphbWVza3V5cGVyQGFsdW1uaS5jYWx0ZWNoLmVkdT4g d2liYmxlZDoNCj4+Pj4gT24gMTEvMjcvMjQgMTE6MTIsIE11dHRsZXlARGFzdGFyZGx5SFEu b3JnIHdyb3RlOg0KPj4+Pj4gT24gV2VkLCAyNyBOb3YgMjAyNCAxNzoyNDowNSArMDIwMA0K Pj4+Pj4gTWljaGFlbCBTIDxhbHJlYWR5NWNob3NlbkB5YWhvby5jb20+IHdpYmJsZWQ6DQo+ Pj4+IC4uLi4NCj4+Pj4+PiBJdCB3b3JrcywgYnV0IGJhZGx5IHJhdGhlciB0aGFuIGZpbmUu DQo+Pj4+Pj4gU3BlY2lmaWNhbGx5LCBpdCB3b3JrcyBvbmx5IHdpdGggQVNDSUkgcGF0aHMu IFdoaWNoLCBvbiBXaW5kb3dzLA0KPj4+Pj4+IGhhcHBlbiB0byBiZSAybmQgY2xhc3MuIFRo ZSBiaWdnZXN0IHByb2JsZW0gd2l0aCBBU0NJSSBwYXRocyBvbg0KPj4+Pj4+IFdpbmRvd3Mg aXMNCj4+Pj4+DQo+Pj4+PiBIb3cgY2FuIGFzY2lpIHBhdGhzIGJlIDJuZCBjbGFzcyAod2hh dGV2ZXIgdGhhdCBtZWFucykgZ2l2ZW4gdGhhdA0KPj4+Pj4gYXNjaWkgaXMgYSBzdWJzZXQg b2YgdXRmLTg/DQo+Pj4+DQo+Pj4+IEJlY2F1c2UgYXNjaWkgaXMgYSBzdWJzZXQgb2YgdXRm LTgsIGFueSBwYXRoIG5hbWUgdGhhdCBjb250YWlucyBhDQo+Pj4+IGNoYXJhY3RlciBub3Qg aW4gdGhhdCBzdWJzZXQgY2Fubm90IGJlIHJlcHJlc2VudGVkLCB3aGljaCBpcyB3aGF0DQo+ Pj4+IG1ha2VzIHRoZW0gMm5kIGNsYXNzLg0KPj4+DQo+Pj4gSHVoPyBBbnkgYXNjaWkgdGV4 dCBpcyB2YWxpZCBpbiBVVEYtOCwgdGhhdCBkb2Vzbid0IG1ha2UgYXNjaWkgMm5kDQo+Pj4g Y2xhc3MuIFRoZSBvbmx5IGlzc3VlIGNvbWVzIHdoZW4gc29tZSBpZGlvdCB0cmllcyB0byBt aXggdXRmLTggd2l0aA0KPj4+IDggYml0IGFzY2lpIGNvZGUgcGFnZXMuDQo+Pg0KPj4gWW91 IGFyZSByaWdodCwgQVNDSUkgaXMgbm90IDJuZCBjbGFzcyBiZWNhdXNlIGl0IGlzIHBhcnQg b2YgVVRGLTguIEl0DQo+PiBpcyAybmQgY2xhc3Mgb24gV2luZG93cyBiZWNhdXNlIE1TIGhh dmUgaGlzdG9yaWNhbGx5IGRlY2lkZWQgdG8gbm90DQo+PiBzdXBwb3J0IFVURi04IHByb3Bl cmx5IG9uIFdpbmRvd3MsIGluIGFuIGF0dGVtcHQgb2YgYSBmdXRpbGUgdmVuZG9yDQo+PiBs b2NrLWluLg0KPj4NCj4gDQo+IE5vdCBzdXJlIHRoYXQgaXQgd2FzIGFib3V0IGxvY2sgaW4u IEF0IHRpbWUgV2luMzIgd2FzIGNvbmNlaXZlZCwgVVRGOA0KPiBkaWRuJ3QgZXhpc3QuIEF0 IHRpbWUgV2luTnQgd2FzIHNoaXBwZWQsIGl0IHN0aWxsIHdhcyBsZXNzIHRoYW4gYQ0KPiB5 ZWFyIG9sZC4gQmFjayB0aGVuIGNob29zaW5nIFVURjE2IGxvb2tlZCByZWFzb25hYmxlLg0K PiBVcCB0byB+MTUgeWVhcnMgYWdvIGl0IHdhcyBub3QgY2xlYXIgdGhhdCBVVEY4IG5vdCBq dXN0IHdvbiwgYnV0IHdvbg0KPiBkZWNpc2l2ZWx5LCBzbyBzaXRpbmcgb24gdGhlIGZlbmNl LCB3YWl0aW5nIGZvciB0aGUgb3V0Y29tZSBvZiB0aGUNCj4gYmF0dGxlIGFuZCByb290aW5n IGZvciBsZWdhY3kgd2FzIG5vdCB0b3RhbGx5IHVucmVhc29uYWJsZS4gRm9yIHdoYXQNCj4g aGFwcGVuZWQgYWZ0ZXIgdGhhdCwgeW91IGNvdWxkIG5vdCB1bmRlcmVzdGltYXRlZCBhIGZh Y3RvciBvZiBsYXppbmVzcy4NCj4gDQo+PiBUaG91Z2ggdGhpcyBpcyBjaGFuZ2luZyBub3cs IEkganVzdCByYW4gYSBxdWljayB0ZXN0IGFuZCBhcHBhcmVudGx5DQo+PiBjYWxsaW5nIHNl dGxvY2FsZShMQ19BTEwsICJldF9FRS5VVEYtOCIpIG5vdyB3b3JrcyBwcm9wZXJseSB3aXRo DQo+PiBWUzIwMjIgb24gV2luZG93cyAxMCBhbmQgSSBjYW4gcGFzcyBVVEYtOCBmaWxlbmFt ZXMgdG8gbmFycm93LXN0cmluZw0KPj4gZm9wZW4oKSBhbmQgdGhleSB3b3JrIHByb3Blcmx5 LiBTbyB0aGVyZSBpcyBwcm9ncmVzcyENCj4+DQo+IA0KPiBDYW4geW91IHRyeSBpdCB3aXRo IHBhdGhzIHRoYXQgYXJlIGxvbmdlciB0aGFuIDI2MCBjaGFyYWN0ZXJzPyBCb3RoDQo+IHBy ZWZpeGVkIHdpdGggIlxcP1wiIGFuZCBub24tcHJlZml4ZWQ/DQo+IA0KDQpOb24tcHJlZml4 ZWQsIF9ta2RpcigpIHN1Y2NlZWRzIHdpdGggYSBwYXRoIG9mIDI0NyB1bmljb2RlIGNoYXJh Y3RlcnMgDQooNDA2IGJ5dGVzKSBhbmQgZmFpbHMgd2l0aCAzMDcgdW5pY29kZSBjaGFycyAo NTA2IGJ5dGVzKS4NCg0KUHJlZml4ZWQgd2l0aCAiXFw/XCIgX21rZGlyKCkgYW5kIGZvcGVu KCkgYXBwZWFyZWQgdG8gd29yayBmaW5lLCB0cmllZCANCnVwIHRvIDEyNzUgdW5pY29kZSBj aGFycyAoMjExNCBieXRlcyksIHRoZSBsYXJnZXN0IHBhdGggd2FzOg0KDQpcXD9cQzpcVG1w XGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw 5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLm vKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8 oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVz dMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zD vMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TD pC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWph cOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi 5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLm vKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1l c3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8 w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOk w6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxq YXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8 oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi 5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKIt ZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TD vMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zD pMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6Qt amFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDm vKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8 oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryi LWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0 w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8 w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOk LWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw 5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLm vKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8 oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVz dMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zD vMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TD pC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWph cOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi 5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLm vKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1l c3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8 w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOk w6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1q YXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLnR4dA0K DQoNCg0KDQpBbGFzLCB0aGUgRmlsZSBFeHBsb3JlciBsZWZ0LWhhbmQgdHJlZSBmYWlsZWQg dG8gZGVzY2VuZCBpbnRvIHNvIGRlZXAgDQpkaXJlY3RvcnkgdHJlZSAoZG91YmxlLWNsaWNr IGluIHJpZ2h0LWhhbmQgcGFuZSB3b3JrZWQsIGJ1dCBsZWZ0LWhhbmQgDQp0cmVlIHdhcyB0 cnVuY2F0ZWQgYXQgc29tZSBwb2ludCkuIFdoZW4gb3BlbmVkIGluIE5vdGVwYWQgb3IgTm90 ZXBhZCsrLCANCnRoZSB0b28gbG9uZyBwYXRocyB3ZXJlIGNoYW5nZWQgaW50byB0aWxkZS1z dHlsZSAic2hvcnQgbmFtZXMiLCANCnN0cmlwcGluZyB0aGUgdW5pY29kZSBjaGFyczoNCg0K QzpcdG1wXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpB UC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpB UC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpB UC1FU34xXEpBUC1FU34xXEpBUC1FU34xXEpBUC1FU34xLlRYVA0KDQoNCg0K

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to [email protected] on Thu Nov 28 17:18:16 2024
    On 11/28/24 03:26, [email protected] wrote:
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    ...
    How can ascii paths be 2nd class (whatever that means) given that ascii
    is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what makes
    them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii 2nd class

    True, what makes it 2nd class is UTF-8 text that is not valid ASCII
    text, exactly the opposite issue.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Paavo Helde on Fri Nov 29 00:21:48 2024
    On Thu, 28 Nov 2024 22:41:42 +0200
    Paavo Helde <[email protected]> wrote:

    On 28.11.2024 15:19, Michael S wrote:
    On Thu, 28 Nov 2024 13:03:20 +0200
    Paavo Helde <[email protected]> wrote:

    On 28.11.2024 10:26, [email protected] wrote:
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ....
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on
    Windows, happen to be 2nd class. The biggest problem with
    ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given
    that ascii is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that contains a
    character not in that subset cannot be represented, which is what
    makes them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii 2nd
    class. The only issue comes when some idiot tries to mix utf-8
    with 8 bit ascii code pages.

    You are right, ASCII is not 2nd class because it is part of UTF-8.
    It is 2nd class on Windows because MS have historically decided to
    not support UTF-8 properly on Windows, in an attempt of a futile
    vendor lock-in.


    Not sure that it was about lock in. At time Win32 was conceived,
    UTF8 didn't exist. At time WinNt was shipped, it still was less
    than a year old. Back then choosing UTF16 looked reasonable.
    Up to ~15 years ago it was not clear that UTF8 not just won, but won decisively, so siting on the fence, waiting for the outcome of the
    battle and rooting for legacy was not totally unreasonable. For what happened after that, you could not underestimated a factor of
    laziness.
    Though this is changing now, I just ran a quick test and apparently
    calling setlocale(LC_ALL, "et_EE.UTF-8") now works properly with
    VS2022 on Windows 10 and I can pass UTF-8 filenames to
    narrow-string fopen() and they work properly. So there is progress!


    Can you try it with paths that are longer than 260 characters? Both prefixed with "\\?\" and non-prefixed?


    Non-prefixed, _mkdir() succeeds with a path of 247 unicode characters
    (406 bytes) and fails with 307 unicode chars (506 bytes).

    Prefixed with "\\?\" _mkdir() and fopen() appeared to work fine,
    tried up to 1275 unicode chars (2114 bytes), the largest path was:

    \\?\C:\Tmp\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-est�
    �üää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüä
    ä\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-
    jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap�
    �漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢�
    ��-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-
    estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estü
    üää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüä�
    �-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää.txt




    Alas, the File Explorer left-hand tree failed to descend into so deep directory tree (double-click in right-hand pane worked, but left-hand
    tree was truncated at some point). When opened in Notepad or
    Notepad++, the too long paths were changed into tilde-style "short
    names", stripping the unicode chars:

    C:\tmp\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1.TXT





    Prefixed Unicode is expected to work fine. Documentation is clear about
    it. I was wondering about behavior of prefixed ASCII. I.e. fopen() with
    default locale.
    My short test with VS2019 appears to work fine on Win7. So far I didn't
    try to dig deeper.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to All on Fri Nov 29 00:59:13 2024
    T24gMjkuMTEuMjAyNCAwMDoyMSwgTWljaGFlbCBTIHdyb3RlOg0KPiBPbiBUaHUsIDI4IE5v diAyMDI0IDIyOjQxOjQyICswMjAwDQo+IFBhYXZvIEhlbGRlIDxlZXNuaW1pQG9zYS5wcmku ZWU+IHdyb3RlOg0KPiANCj4+IE9uIDI4LjExLjIwMjQgMTU6MTksIE1pY2hhZWwgUyB3cm90 ZToNCj4+PiBPbiBUaHUsIDI4IE5vdiAyMDI0IDEzOjAzOjIwICswMjAwDQo+Pj4gUGFhdm8g SGVsZGUgPGVlc25pbWlAb3NhLnByaS5lZT4gd3JvdGU6DQo+Pj4gICAgDQo+Pj4+IE9uIDI4 LjExLjIwMjQgMTA6MjYsIE11dHRsZXlARGFzdGFyZGx5SFEub3JnIHdyb3RlOg0KPj4+Pj4g T24gV2VkLCAyNyBOb3YgMjAyNCAxNDo1ODoxOCAtMDUwMA0KPj4+Pj4gSmFtZXMgS3V5cGVy IDxqYW1lc2t1eXBlckBhbHVtbmkuY2FsdGVjaC5lZHU+IHdpYmJsZWQ6DQo+Pj4+Pj4gT24g MTEvMjcvMjQgMTE6MTIsIE11dHRsZXlARGFzdGFyZGx5SFEub3JnIHdyb3RlOg0KPj4+Pj4+ PiBPbiBXZWQsIDI3IE5vdiAyMDI0IDE3OjI0OjA1ICswMjAwDQo+Pj4+Pj4+IE1pY2hhZWwg UyA8YWxyZWFkeTVjaG9zZW5AeWFob28uY29tPiB3aWJibGVkOg0KPj4+Pj4+IC4uLi4NCj4+ Pj4+Pj4+IEl0IHdvcmtzLCBidXQgYmFkbHkgcmF0aGVyIHRoYW4gZmluZS4NCj4+Pj4+Pj4+ IFNwZWNpZmljYWxseSwgaXQgd29ya3Mgb25seSB3aXRoIEFTQ0lJIHBhdGhzLiBXaGljaCwg b24NCj4+Pj4+Pj4+IFdpbmRvd3MsIGhhcHBlbiB0byBiZSAybmQgY2xhc3MuIFRoZSBiaWdn ZXN0IHByb2JsZW0gd2l0aA0KPj4+Pj4+Pj4gQVNDSUkgcGF0aHMgb24gV2luZG93cyBpcw0K Pj4+Pj4+Pg0KPj4+Pj4+PiBIb3cgY2FuIGFzY2lpIHBhdGhzIGJlIDJuZCBjbGFzcyAod2hh dGV2ZXIgdGhhdCBtZWFucykgZ2l2ZW4NCj4+Pj4+Pj4gdGhhdCBhc2NpaSBpcyBhIHN1YnNl dCBvZiB1dGYtOD8NCj4+Pj4+Pg0KPj4+Pj4+IEJlY2F1c2UgYXNjaWkgaXMgYSBzdWJzZXQg b2YgdXRmLTgsIGFueSBwYXRoIG5hbWUgdGhhdCBjb250YWlucyBhDQo+Pj4+Pj4gY2hhcmFj dGVyIG5vdCBpbiB0aGF0IHN1YnNldCBjYW5ub3QgYmUgcmVwcmVzZW50ZWQsIHdoaWNoIGlz IHdoYXQNCj4+Pj4+PiBtYWtlcyB0aGVtIDJuZCBjbGFzcy4NCj4+Pj4+DQo+Pj4+PiBIdWg/ IEFueSBhc2NpaSB0ZXh0IGlzIHZhbGlkIGluIFVURi04LCB0aGF0IGRvZXNuJ3QgbWFrZSBh c2NpaSAybmQNCj4+Pj4+IGNsYXNzLiBUaGUgb25seSBpc3N1ZSBjb21lcyB3aGVuIHNvbWUg aWRpb3QgdHJpZXMgdG8gbWl4IHV0Zi04DQo+Pj4+PiB3aXRoIDggYml0IGFzY2lpIGNvZGUg cGFnZXMuDQo+Pj4+DQo+Pj4+IFlvdSBhcmUgcmlnaHQsIEFTQ0lJIGlzIG5vdCAybmQgY2xh c3MgYmVjYXVzZSBpdCBpcyBwYXJ0IG9mIFVURi04Lg0KPj4+PiBJdCBpcyAybmQgY2xhc3Mg b24gV2luZG93cyBiZWNhdXNlIE1TIGhhdmUgaGlzdG9yaWNhbGx5IGRlY2lkZWQgdG8NCj4+ Pj4gbm90IHN1cHBvcnQgVVRGLTggcHJvcGVybHkgb24gV2luZG93cywgaW4gYW4gYXR0ZW1w dCBvZiBhIGZ1dGlsZQ0KPj4+PiB2ZW5kb3IgbG9jay1pbi4NCj4+Pj4gICANCj4+Pg0KPj4+ IE5vdCBzdXJlIHRoYXQgaXQgd2FzIGFib3V0IGxvY2sgaW4uIEF0IHRpbWUgV2luMzIgd2Fz IGNvbmNlaXZlZCwNCj4+PiBVVEY4IGRpZG4ndCBleGlzdC4gQXQgdGltZSBXaW5OdCB3YXMg c2hpcHBlZCwgaXQgc3RpbGwgd2FzIGxlc3MNCj4+PiB0aGFuIGEgeWVhciBvbGQuIEJhY2sg dGhlbiBjaG9vc2luZyBVVEYxNiBsb29rZWQgcmVhc29uYWJsZS4NCj4+PiBVcCB0byB+MTUg eWVhcnMgYWdvIGl0IHdhcyBub3QgY2xlYXIgdGhhdCBVVEY4IG5vdCBqdXN0IHdvbiwgYnV0 IHdvbg0KPj4+IGRlY2lzaXZlbHksIHNvIHNpdGluZyBvbiB0aGUgZmVuY2UsIHdhaXRpbmcg Zm9yIHRoZSBvdXRjb21lIG9mIHRoZQ0KPj4+IGJhdHRsZSBhbmQgcm9vdGluZyBmb3IgbGVn YWN5IHdhcyBub3QgdG90YWxseSB1bnJlYXNvbmFibGUuIEZvciB3aGF0DQo+Pj4gaGFwcGVu ZWQgYWZ0ZXIgdGhhdCwgeW91IGNvdWxkIG5vdCB1bmRlcmVzdGltYXRlZCBhIGZhY3RvciBv Zg0KPj4+IGxhemluZXNzLg0KPj4+PiBUaG91Z2ggdGhpcyBpcyBjaGFuZ2luZyBub3csIEkg anVzdCByYW4gYSBxdWljayB0ZXN0IGFuZCBhcHBhcmVudGx5DQo+Pj4+IGNhbGxpbmcgc2V0 bG9jYWxlKExDX0FMTCwgImV0X0VFLlVURi04Iikgbm93IHdvcmtzIHByb3Blcmx5IHdpdGgN Cj4+Pj4gVlMyMDIyIG9uIFdpbmRvd3MgMTAgYW5kIEkgY2FuIHBhc3MgVVRGLTggZmlsZW5h bWVzIHRvDQo+Pj4+IG5hcnJvdy1zdHJpbmcgZm9wZW4oKSBhbmQgdGhleSB3b3JrIHByb3Bl cmx5LiBTbyB0aGVyZSBpcyBwcm9ncmVzcyENCj4+Pj4gICANCj4+Pg0KPj4+IENhbiB5b3Ug dHJ5IGl0IHdpdGggcGF0aHMgdGhhdCBhcmUgbG9uZ2VyIHRoYW4gMjYwIGNoYXJhY3RlcnM/ IEJvdGgNCj4+PiBwcmVmaXhlZCB3aXRoICJcXD9cIiBhbmQgbm9uLXByZWZpeGVkPw0KPj4+ ICAgIA0KPj4NCj4+IE5vbi1wcmVmaXhlZCwgX21rZGlyKCkgc3VjY2VlZHMgd2l0aCBhIHBh dGggb2YgMjQ3IHVuaWNvZGUgY2hhcmFjdGVycw0KPj4gKDQwNiBieXRlcykgYW5kIGZhaWxz IHdpdGggMzA3IHVuaWNvZGUgY2hhcnMgKDUwNiBieXRlcykuDQo+Pg0KPj4gUHJlZml4ZWQg d2l0aCAiXFw/XCIgX21rZGlyKCkgYW5kIGZvcGVuKCkgYXBwZWFyZWQgdG8gd29yayBmaW5l LA0KPj4gdHJpZWQgdXAgdG8gMTI3NSB1bmljb2RlIGNoYXJzICgyMTE0IGJ5dGVzKSwgdGhl IGxhcmdlc3QgcGF0aCB3YXM6DQo+Pg0KPj4gXFw/XEM6XFRtcFxqYXDmvKLmvKLmvKItZXN0 w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8 w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOk LWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw 5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLm vKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8 oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVz dMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zD vMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TD pC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGph cOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi 5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLm vKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1l c3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8 w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOk w6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1q YXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8 oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi 5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKIt ZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TD vMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zD pMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6Qt amFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDm vKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8 oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryi LWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0 w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8 w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOk LWphcOa8oua8oua8oi1lc3TDvMO8w6TDpFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw 5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLm vKLmvKItZXN0w7zDvMOkw6RcamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8 oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVz dMO8w7zDpMOkXGphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zD vMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TD pFxqYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkLWph cOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6RcamFw5ryi 5ryi5ryiLWVzdMO8w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC1qYXDmvKLmvKLm vKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8w7zDpMOkXGphcOa8oua8oua8oi1l c3TDvMO8w6TDpC1qYXDmvKLmvKLmvKItZXN0w7zDvMOkw6QtamFw5ryi5ryi5ryiLWVzdMO8 w7zDpMOkLWphcOa8oua8oua8oi1lc3TDvMO8w6TDpC50eHQNCj4+DQo+Pg0KPj4NCj4+DQo+ PiBBbGFzLCB0aGUgRmlsZSBFeHBsb3JlciBsZWZ0LWhhbmQgdHJlZSBmYWlsZWQgdG8gZGVz Y2VuZCBpbnRvIHNvIGRlZXANCj4+IGRpcmVjdG9yeSB0cmVlIChkb3VibGUtY2xpY2sgaW4g cmlnaHQtaGFuZCBwYW5lIHdvcmtlZCwgYnV0IGxlZnQtaGFuZA0KPj4gdHJlZSB3YXMgdHJ1 bmNhdGVkIGF0IHNvbWUgcG9pbnQpLiBXaGVuIG9wZW5lZCBpbiBOb3RlcGFkIG9yDQo+PiBO b3RlcGFkKyssIHRoZSB0b28gbG9uZyBwYXRocyB3ZXJlIGNoYW5nZWQgaW50byB0aWxkZS1z dHlsZSAic2hvcnQNCj4+IG5hbWVzIiwgc3RyaXBwaW5nIHRoZSB1bmljb2RlIGNoYXJzOg0K Pj4NCj4+IEM6XHRtcFxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAt RVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAt RVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAt RVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MVxKQVAtRVN+MS5UWFQNCj4+DQo+Pg0K Pj4NCj4gDQo+IA0KPiBQcmVmaXhlZCBVbmljb2RlIGlzIGV4cGVjdGVkIHRvIHdvcmsgZmlu ZS4gRG9jdW1lbnRhdGlvbiBpcyBjbGVhciBhYm91dA0KPiBpdC4gSSB3YXMgd29uZGVyaW5n IGFib3V0IGJlaGF2aW9yIG9mIHByZWZpeGVkIEFTQ0lJLiBJLmUuIGZvcGVuKCkgd2l0aA0K PiBkZWZhdWx0IGxvY2FsZS4NCg0KV2l0aCBkZWZhdWx0IGxvY2FsZSBpdCBkaWQgbm90IHdv cmsgb24gbXkgbWFjaGluZSAoaS5lLiBwcm9kdWNlZCANCmdpYmJlcmlzaCBmaWxlbmFtZXMg aW5zdGVhZCBvZiBleHBlY3RlZCBVbmljb2RlIGNoYXJhY3RlcnMpLCBlLmcuIA0KamFww6bC vMKiw6bCvMKiw6bCvMKiLWVzdMODwrzDg8K8w4PCpMODwqQtamFww6bCvMKiw6bCvMKiw6bC vMKiLWVzdMODwrzDg8K8w4PCpMODwqQtamFww6bCvMKiw6bCvMKiw6bCvMKiLWVzdMODwrzD g8K8w4PCpMODwqQtamFww6bCvMKiw6bCvMKiw6bCvMKiLWVzdMODwrzDg8K8w4PCpMODwqQN Cg0KSG93ZXZlciwgYWZ0ZXINCg0Kc2V0bG9jYWxlKExDX0FMTCwgIi5VVEYtOCIpOw0KDQp0 aGUgbmFycm93IGNoYXJhY3RlciBfbWtkaXIoKSBhbmQgZm9wZW4oKSBzdGFydGVkIHRvIHdv cmsgZmluZS4NCg0KSWYgeW91IGNhbiBzZXQgeW91ciBXaW5kb3dzIEFDUCB0byBVVEYtOCwg dGhlbiB0aGUgZGVmYXVsdCBsb2NhbGUgb3VnaHQgDQp0byB3b3JrIGFzIHdlbGwgSSBndWVz cy4gSSB0aGluayBsYXN0IHRpbWUgSSB0cmllZCB0aGlzIHRoZSBtYWNoaW5lIGRpZCANCm5v dCBib290IHVwIGFueSBtb3JlLiBCdXQgdGhpcyB3YXMgbWFueSB5ZWFycyBhZ28uDQoNCg0K
    DQo=

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Paavo Helde on Fri Nov 29 01:20:17 2024
    On Fri, 29 Nov 2024 00:59:13 +0200
    Paavo Helde <[email protected]> wrote:

    On 29.11.2024 00:21, Michael S wrote:
    On Thu, 28 Nov 2024 22:41:42 +0200
    Paavo Helde <[email protected]> wrote:

    On 28.11.2024 15:19, Michael S wrote:
    On Thu, 28 Nov 2024 13:03:20 +0200
    Paavo Helde <[email protected]> wrote:

    On 28.11.2024 10:26, [email protected] wrote:
    On Wed, 27 Nov 2024 14:58:18 -0500
    James Kuyper <[email protected]> wibbled:
    On 11/27/24 11:12, [email protected] wrote:
    On Wed, 27 Nov 2024 17:24:05 +0200
    Michael S <[email protected]> wibbled:
    ....
    It works, but badly rather than fine.
    Specifically, it works only with ASCII paths. Which, on
    Windows, happen to be 2nd class. The biggest problem with
    ASCII paths on Windows is

    How can ascii paths be 2nd class (whatever that means) given
    that ascii is a subset of utf-8?

    Because ascii is a subset of utf-8, any path name that
    contains a character not in that subset cannot be represented,
    which is what makes them 2nd class.

    Huh? Any ascii text is valid in UTF-8, that doesn't make ascii
    2nd class. The only issue comes when some idiot tries to mix
    utf-8 with 8 bit ascii code pages.

    You are right, ASCII is not 2nd class because it is part of
    UTF-8. It is 2nd class on Windows because MS have historically
    decided to not support UTF-8 properly on Windows, in an attempt
    of a futile vendor lock-in.


    Not sure that it was about lock in. At time Win32 was conceived,
    UTF8 didn't exist. At time WinNt was shipped, it still was less
    than a year old. Back then choosing UTF16 looked reasonable.
    Up to ~15 years ago it was not clear that UTF8 not just won, but
    won decisively, so siting on the fence, waiting for the outcome
    of the battle and rooting for legacy was not totally
    unreasonable. For what happened after that, you could not
    underestimated a factor of laziness.
    Though this is changing now, I just ran a quick test and
    apparently calling setlocale(LC_ALL, "et_EE.UTF-8") now works
    properly with VS2022 on Windows 10 and I can pass UTF-8
    filenames to narrow-string fopen() and they work properly. So
    there is progress!

    Can you try it with paths that are longer than 260 characters?
    Both prefixed with "\\?\" and non-prefixed?


    Non-prefixed, _mkdir() succeeds with a path of 247 unicode
    characters (406 bytes) and fails with 307 unicode chars (506
    bytes).

    Prefixed with "\\?\" _mkdir() and fopen() appeared to work fine,
    tried up to 1275 unicode chars (2114 bytes), the largest path was:

    \\?\C:\Tmp\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-
    estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estü
    üää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüä�
    �-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\
    jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap�
    �漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢�
    ��-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-
    estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää\jap漢漢漢-estü
    üää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää.txt




    Alas, the File Explorer left-hand tree failed to descend into so
    deep directory tree (double-click in right-hand pane worked, but
    left-hand tree was truncated at some point). When opened in
    Notepad or Notepad++, the too long paths were changed into
    tilde-style "short names", stripping the unicode chars:

    C:\tmp\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1\JAP-ES~1.TXT





    Prefixed Unicode is expected to work fine. Documentation is clear
    about it. I was wondering about behavior of prefixed ASCII. I.e.
    fopen() with default locale.

    With default locale it did not work on my machine (i.e. produced
    gibberish filenames instead of expected Unicode characters), e.g. jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää-jap漢漢漢-estüüää

    However, after

    setlocale(LC_ALL, ".UTF-8");

    the narrow character _mkdir() and fopen() started to work fine.

    If you can set your Windows ACP to UTF-8, then the default locale
    ought to work as well I guess. I think last time I tried this the
    machine did not boot up any more. But this was many years ago.




    I did not have Japanese names in mind. I was asking about very long
    paths consisting of Latin characters.
    In my tests, which are written in C rather than in C++, they appear to
    work fine. So, it seems, my claim that ASCII is 2nd is either outdated
    or plain wrong. The OS (Win7) appears to work better than claimed by
    docs.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rosario19@21:1/5 to [email protected] on Sat Nov 30 16:52:47 2024
    On Tue, 26 Nov 2024 10:20:07 +0100, "Fred. Zwarts"
    <[email protected]> wrote:

    Op 25.nov.2024 om 22:20 schreef Rosario19:
    On Wed, 20 Nov 2024 11:02:49 +0800, wij <[email protected]> wrote:

    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. >>> But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of >>> programs for some reason, but generally, exit code of program is a numerical
    value. Why EXIT_SUCCESS?

    because the success is one only case
    and failure can happen for 10000000 of causes differents
    the success has to be one number
    and failure all the remain numbers
    as example 0 success -inf .. +inf -{0} failure

    In some situations there can be different success cases, as well.
    E.g. when searching for something, both finding something and finding
    nothing is a valuable result and not a failure of the search operation.
    It is worthwhile to indicate them with different success codes.

    ok but for me it is better "What return" is the error code, and the
    number of results it finds can be in a variable linked to the function

    That can be done in VMS where odd codes are all success codes.
    One could also think of a success code that includes the number of
    results. (That is what many I/O functions do: A positive value indicates
    a success with the number of bytes transferred, a negative number
    indicates a failure.)
    Failures are a different thing; they make the result of the operation >invalid. They should be indicated with an error code.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Sun Dec 1 21:00:20 2024
    Keith Thompson <[email protected]> writes:

    Keith Thompson <[email protected]> writes:
    [...]

    In my opinion, the main reason for NULL is that it lets the
    programmer explicitly state that it's a null pointer constant and
    not just zero. (But NULL can still be of type int.) I find
    nullptr (in C++ and C23) an improvement over NULL.

    To summarize, the purpose of using NULL rather than 0 is to
    communicate information to the human reader, [...]

    That is one purpose for using NULL, but it doesn't have to
    be the only one.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Sun Dec 1 20:57:05 2024
    Keith Thompson <[email protected]> writes:

    David Brown <[email protected]> writes:
    [...]

    I don't know if there are any real-world implementations (of C or
    C++) with more than one representation for null pointers, but
    null pointers are somewhat special. "if (x == y)" compares for
    equality of two values, unless one of these is a pointer and the
    other is a null pointer constant - then the comparison is more of
    a classification, checking if the pointer is in the set of null
    pointer values.

    [...]

    I'd say that a null pointer of a given type is a single *value*
    that may or may not have multiple *representations*. [...]

    That's a point of view, but it isn't anything more than that. The
    abstract value space of pointers is not well defined. By contrast,
    the abstract value space of an integer data type, such as int, is
    well defined. Two pointers can compare equal and yet not be the
    same pointer. There is no reason the same relationship can't
    hold for null pointers. (In both of the last two sentences the
    word "pointer" may be read as "pointer value".)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to wij on Sat Feb 15 16:21:47 2025
    On Tue 11/19/2024 7:02 PM, wij wrote:
    EXIT_SUCCESS/EXIT_FAILURE are for communication between different programs. But, is it necessary? E.g. can it be put into shell script?
    I think the macro EXIT_SUCCESS/EXIT_FAILURE may be good within a group of programs for some reason, but generally, exit code of program is a numerical value. Why EXIT_SUCCESS?

    On can point out that `EXIT_SUCCESS` is "not necessary" in exactly the
    same way macro `NULL` is "not necessary".

    The language spec explicitly states that every time you do return `0`
    from `main`, the actual value returned to the hosting environment is the environment-specific "success" value. It means that when you do `return
    0`, it does not mean that integer `0` is actually returned to the host
    (even on systems that support integral returns). The environment might
    actually receive `1`, `42`, `255`, `3.14` or "ok". The implementation is required to _translate_ the value. And the process of translation of `0`
    into the appropriate "success value" in return-from-main contexts takes
    place outside of `EXIT_SUCCESS` macro. Regardless of how `EXIT_SUCCESS`
    is defined, you can always return `0` instead of returning
    `EXIT_SUCCESS` and get the same effect. Implementations are free to
    define `EXIT_SUCCESS` as something different from `0`, but there's no
    need to since defining it as `0` will always work anyway.

    This is very similar to `NULL`: you can always use `0` in place of
    `NULL`, and while it is possible to define `NULL` as something different
    from `0`, defining it as `0` will always work anyway. So, is `NULL`
    necessary or unnecessary?

    Meanwhile, `EXIT_FAILURE` is different, since there's no translation
    mechanism for non-zero return values. And this might hint at one reason
    for `EXIT_FAILURE`'s existence: since the "success" value is not
    necessarily zero (on the host's side), using an arbitrary non-zero value
    as a "failure" value might result in an unintended collision with
    devastating consequences. For example, the host might use integer 255 as
    the "success" value (meaning that `return 0` will actually result in 255
    being returned to the host), whilst the program's author might
    unknowingly employ 255 as indicator of some specific error. If
    non-translated integer 255 ends up returned to the host, the host will
    see it as a success value. This is where `EXIT_FAILURE` comes in. `EXIT_FAILURE` is there to provide you with _at_ _least_ _one_ return
    value that _definitely_ does not collide with "success" value on the
    host's side.

    So, `EXIT_SUCCESS` is not necessary, aside from providing optimistically-sounding mnemonic. `EXIT_FAILURE` is kinda necessary...
    albeit it provides the kind of portability that is usually left
    unrequested in practice.

    --
    Best regards,
    Andrey

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