• is a comma required for initializing a std::string array?

    From Lynn McGuire@3:633/10 to All on Thu Jun 11 18:43:27 2026
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    Thanks,
    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From James Kuyper@3:633/10 to All on Thu Jun 11 20:53:18 2026
    On 2026-06-11 19:43, Lynn McGuire wrote:
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };\

    Those string literals get catenated during translation phase 5, so the
    above is equivalent to

    std::string strings[5] = {" 1343222440"};

    I doubt that is what you intended. String literal catenation can be very
    useful in certain contexts, but it creates a trap for the unwary.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Thu Jun 11 18:38:02 2026
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    It compiles, but it doesn't mean what you probably think it means.

    Adjacent string literals are concatenated in translation phase 5,
    which is typically part of the preprocessor. (C does the same thing
    in translation phase 6.) (This allows a program to have very long
    strings without exceeding line length limitations or using ugly
    backslash line continuation.)

    So your declaration is equivalent to:

    std::string strings [5] = { " 1343222440" };

    The string literal is used to initialize strings[0], and the other 4
    elements are default-initialized.

    Yeah, you need the commas.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Thu Jun 11 21:50:48 2026
    On 6/11/2026 7:53 PM, James Kuyper wrote:
    On 2026-06-11 19:43, Lynn McGuire wrote:
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };\

    Those string literals get catenated during translation phase 5, so the
    above is equivalent to

    std::string strings[5] = {" 1343222440"};

    I doubt that is what you intended. String literal catenation can be very useful in certain contexts, but it creates a trap for the unwary.

    Thanks, that is what I suddenly realized. My F to C++ translator is not putting commas into into the character string arrays. But it compiled
    ok which threw me until I suddenly realized that the C/C++ compilers
    like to join those character strings together unless they are comma
    delimited.

    Thanks again,
    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Thu Jun 11 22:01:07 2026
    On 6/11/2026 8:38 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    It compiles, but it doesn't mean what you probably think it means.

    Adjacent string literals are concatenated in translation phase 5,
    which is typically part of the preprocessor. (C does the same thing
    in translation phase 6.) (This allows a program to have very long
    strings without exceeding line length limitations or using ugly
    backslash line continuation.)

    So your declaration is equivalent to:

    std::string strings [5] = { " 1343222440" };

    The string literal is used to initialize strings[0], and the other 4
    elements are default-initialized.

    Yeah, you need the commas.

    Thanks, that is what I suddenly realized. My F to C++ translator is not putting commas into the character string arrays, in fact it is removing
    the commas from the F77 code. But it compiled ok which threw me until I suddenly realized that the C/C++ compilers like to join those character strings together unless they are comma delimited.

    Thanks again,
    Lynn

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jun 11 21:13:32 2026
    On 6/11/2026 4:43 PM, Lynn McGuire wrote:
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };
    "Not" " For " "This"

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jun 11 21:14:20 2026
    On 6/11/2026 9:13 PM, Chris M. Thomasson wrote:
    On 6/11/2026 4:43 PM, Lynn McGuire wrote:
    Hi, is a comma required for initializing a std::string array?

    This compiles without error on Visual C++ 2015:

    std::string strings [5] = { " " "1" "3432" "2244" "0" };
    "Not" " For " "This"

    "Perhaps", " For ", "This?"

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Jun 12 09:58:28 2026
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:

    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    This is currently planned for C++28.


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Fri Jun 12 15:06:34 2026
    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:

    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    This is currently planned for C++28.

    A new error or to initialize the string array properly ?

    Got a URL ?

    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Fri Jun 12 14:51:25 2026
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:
    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };
    This is currently planned for C++28.

    A new error or to initialize the string array properly ?

    Got a URL ?

    I'm skeptical that there's any planned change that would change the
    semantics of the above declaration. Concatenation of string literals
    happens in an early translation phase. The above declaration is
    already perfectly meaningful; quietly changing its meaning is not
    a viable option.

    Looking through the git repo for the C++ standard, I see some
    discussion about concatenation of string literals with different
    prefixes, such as "Lfoo" "u"bar", but nothing relevant here.

    (I don't read Bonita's posts, so if she responds I won't see it.)

    Even if there were such a proposal, fixing the bug in your Fortran to
    C++ translator so it adds the commas would still be a better solution.
    (I'm assuming it's a bug, but I can't be sure without seeing and
    understanding the input Fortran code.)

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Fri Jun 12 17:35:46 2026
    On 6/12/2026 4:51 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:
    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };
    This is currently planned for C++28.

    A new error or to initialize the string array properly ?

    Got a URL ?

    I'm skeptical that there's any planned change that would change the
    semantics of the above declaration. Concatenation of string literals
    happens in an early translation phase. The above declaration is
    already perfectly meaningful; quietly changing its meaning is not
    a viable option.

    Looking through the git repo for the C++ standard, I see some
    discussion about concatenation of string literals with different
    prefixes, such as "Lfoo" "u"bar", but nothing relevant here.

    (I don't read Bonita's posts, so if she responds I won't see it.)

    Even if there were such a proposal, fixing the bug in your Fortran to
    C++ translator so it adds the commas would still be a better solution.
    (I'm assuming it's a bug, but I can't be sure without seeing and understanding the input Fortran code.)

    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB"
    "VSTB" "TCTB" "TCTB";

    Here is the code I ended up with:

    const int numItems = 9;
    static std::string ibnk[numItems] = { "CPTB", "VPTB", "LVTB",
    "LHTB", "STTB", "VSTB", "VSTB", "TCTB", "TCTB" };

    Thanks,
    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Fri Jun 12 16:11:07 2026
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/12/2026 4:51 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:
    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };
    This is currently planned for C++28.

    A new error or to initialize the string array properly ?

    Got a URL ?
    I'm skeptical that there's any planned change that would change the
    semantics of the above declaration. Concatenation of string literals
    happens in an early translation phase. The above declaration is
    already perfectly meaningful; quietly changing its meaning is not
    a viable option.
    Looking through the git repo for the C++ standard, I see some
    discussion about concatenation of string literals with different
    prefixes, such as "Lfoo" "u"bar", but nothing relevant here.
    (I don't read Bonita's posts, so if she responds I won't see it.)
    Even if there were such a proposal, fixing the bug in your Fortran
    to
    C++ translator so it adds the commas would still be a better solution.
    (I'm assuming it's a bug, but I can't be sure without seeing and
    understanding the input Fortran code.)

    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB"
    "VSTB" "TCTB" "TCTB";

    That's almost valid C++ code, but with a very different meaning
    than the Fortran (if I understand it correctly) and from what you
    intended. It defines a 1-dimensional array of characters with the
    4-character strings just concatenated together. I guess Fortran
    doesn't use null characters as string terminators.

    It would be valid in C, where, as a special case, this:
    char foo[3] = "foo";
    doesn't store the trailing '\0'. C++ doesn't have that rule, so the initializer is too long.

    It looks like you're having to do a lot of manual cleanup. I don't
    know whether it would be worthwhile to fix the translator so the
    generated code is closer to being correct. If the goal is discard
    (or at least archive) the Fortran code and translator once you have
    a working C++ version, it might not be. But having it insert
    those commas automatically might be a good thing.

    Here is the code I ended up with:

    const int numItems = 9;
    static std::string ibnk[numItems] = { "CPTB", "VPTB", "LVTB",
    "LHTB", "STTB", "VSTB", "VSTB", "TCTB", "TCTB" };

    constexpr might be cleaner than const if you're using C++11 or later.
    Another alternative might be:

    static const char *const ibnk[] = {
    "CPTB", "VPTB", "LVTB",
    "LHTB", "STTB", "VSTB",
    "VSTB", "TCTB", "TCTB"
    };

    if you don't need the extra features of std::string.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Fri Jun 12 18:51:08 2026
    On 6/12/2026 6:11 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/12/2026 4:51 PM, Keith Thompson wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:
    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };
    This is currently planned for C++28.

    A new error or to initialize the string array properly ?

    Got a URL ?
    I'm skeptical that there's any planned change that would change the
    semantics of the above declaration. Concatenation of string literals
    happens in an early translation phase. The above declaration is
    already perfectly meaningful; quietly changing its meaning is not
    a viable option.
    Looking through the git repo for the C++ standard, I see some
    discussion about concatenation of string literals with different
    prefixes, such as "Lfoo" "u"bar", but nothing relevant here.
    (I don't read Bonita's posts, so if she responds I won't see it.)
    Even if there were such a proposal, fixing the bug in your Fortran
    to
    C++ translator so it adds the commas would still be a better solution.
    (I'm assuming it's a bug, but I can't be sure without seeing and
    understanding the input Fortran code.)

    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB"
    "VSTB" "TCTB" "TCTB";

    That's almost valid C++ code, but with a very different meaning
    than the Fortran (if I understand it correctly) and from what you
    intended. It defines a 1-dimensional array of characters with the 4-character strings just concatenated together. I guess Fortran
    doesn't use null characters as string terminators.

    It would be valid in C, where, as a special case, this:
    char foo[3] = "foo";
    doesn't store the trailing '\0'. C++ doesn't have that rule, so the initializer is too long.

    It looks like you're having to do a lot of manual cleanup. I don't
    know whether it would be worthwhile to fix the translator so the
    generated code is closer to being correct. If the goal is discard
    (or at least archive) the Fortran code and translator once you have
    a working C++ version, it might not be. But having it insert
    those commas automatically might be a good thing.

    Here is the code I ended up with:

    const int numItems = 9;
    static std::string ibnk[numItems] = { "CPTB", "VPTB", "LVTB",
    "LHTB", "STTB", "VSTB", "VSTB", "TCTB", "TCTB" };

    constexpr might be cleaner than const if you're using C++11 or later.
    Another alternative might be:

    static const char *const ibnk[] = {
    "CPTB", "VPTB", "LVTB",
    "LHTB", "STTB", "VSTB",
    "VSTB", "TCTB", "TCTB"
    };

    if you don't need the extra features of std::string.

    Fortran character strings are blank padded, not null terminated. Very different from C strings and C++ std::string.

    Yes, too much manual cleanup. I am moving my two calculation engines
    from F77 to C++. 800,000 lines of F77 code, 50,000 lines of C code. I
    am about a quarter done. I am very close to hitting a benchmark step to validate my work so far.

    I was hoping for 80% translation but I am probably getting 70%
    translation. Much better than 0% translation though. I am porting to
    Visual C++ 2015 as my users are on Windows XP to Windows 11. And a few
    Macs running Parallels.

    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Sat Jun 13 06:06:49 2026
    Am 12.06.2026 um 23:51 schrieb Keith Thompson:

    Even if there were such a proposal, fixing the bug in your Fortran to
    C++ translator ...

    Lynn, do you really get pragmatic and readable C++ code with that ?

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Sat Jun 13 00:58:28 2026
    On 6/12/2026 11:06 PM, Bonita Montero wrote:
    Am 12.06.2026 um 23:51 schrieb Keith Thompson:

    Even if there were such a proposal, fixing the bug in your Fortran to
    C++ translator ...

    Lynn, do you really get pragmatic and readable C++ code with that ?

    As readable as the Fortran code was. Sometimes good, sometimes not so
    good. And it is more C code actually than C++ code but with the strong
    typing and other benefits of the C++ compiler.

    IF (IWRITE) 1,3,1
    1 WRITE(OUFILE,2)
    2 FORMAT ('1',4X,'THE FOLLOWING OUTPUT IS PROVIDED BY SUBROUTINE
    NOLSQC '//)
    IPC=0
    GO TO 3

    becomes:

    if (iwrite != 0) {
    goto L1;
    } else {
    goto L3;
    }
    L1:
    // WRITE(OUFILE,2)
    // 2 FORMAT ('1',4X,'THE FOLLOWING OUTPUT IS PROVIDED BY SUBROUTINE NOLSQC '//)
    ptitle ();
    outwri (" THE FOLLOWING OUTPUT IS PROVIDED BY SUBROUTINE
    NOLSQC\n\n");
    ipc = 0;
    goto L3;

    Lynn




    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From James Kuyper@3:633/10 to All on Sat Jun 13 18:25:48 2026
    On 2026-06-12 18:35, Lynn McGuire wrote:
    ...
    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB" "VSTB" "TCTB" "TCTB";
    Is it possible that one of your changes broke something? That would not
    be an accurate translation of the fortran code for any version of C, not
    even the oldest.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Sat Jun 13 17:52:37 2026
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    On 2026-06-12 18:35, Lynn McGuire wrote:
    ...
    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB"
    "VSTB" "TCTB" "TCTB";

    Is it possible that one of your changes broke something? That would not
    be an accurate translation of the fortran code for any version of C, not
    even the oldest.

    No, the original f2c does this -- and it appears to be correct.
    I think f2c is designed to generate C code that behaves the same
    way as its input Fortran code, *not* to generate C code that's
    expected to be maintained in that form. A tool to do the latter
    could be very useful, but probably much harder to implement.

    I was able to turn the above Fortan into a complete working program.
    (Without the print, f2c eliminated the declaration of IBNK, since
    it was unused.)

    program lynn

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    print '(a)', IBNK(2)
    end

    When I compile it with gfortran, the output is:

    VPTB

    which is what I expected. When I feed to f2c version 20200916, the
    generated C code includes the following:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB" "VSTB"
    "TCTB" "TCTB";

    But it also includes this:

    do_fio(&c__1, ibnk + 4, (ftnlen)4);

    which looks (to me) like correct code to extract and print the
    characters "VPTB" from the char array ibnk.

    f2c might sensibly have used a single string literal "CPTBVPTBLVTBLHTBSTTBVSTBVSTBTCTBTCTB", but that could run into
    problems with line length.

    I haven't been able (after not trying very hard) to get the generated
    C code to compile and execute correctly.

    I *think* the Fortran declaration of IBNK specifies that it contains
    the consecutive characters "CPTBVPTBLVTBLHTBSTTBVSTBVSTBTCTBTCTB",
    and any code that extracts a 4-character element has to know the
    dimensions. The generated C code appears to do the same thing,
    correctly as far as I can tell.

    The problem is that the generated C code is very un-C-like, and even
    more un-C++-like -- and apparently Lynn was (quite understandably)
    thrown off by the odd use of string literal concatenation. Changing
    this automatically generated C written with a strong Fortran accent
    to C++ code using std::string almost has to be done manually, while
    referring back to the input Fortran code to understand how it's
    supposed to behave. Doing that reliably requires a strong knowledge
    of both Fortran and C++, and even so is likely to be error-prone.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Sat Jun 13 22:25:28 2026
    On 6/13/2026 5:25 PM, James Kuyper wrote:
    On 2026-06-12 18:35, Lynn McGuire wrote:
    ...
    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB"
    "VSTB" "TCTB" "TCTB";
    Is it possible that one of your changes broke something? That would not
    be an accurate translation of the fortran code for any version of C, not
    even the oldest.

    Nope. That is the way that F2C works for Fortran character string
    arrays. It is very primitive but it works. This why I convert all of
    these to std::string manually.

    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris Ahlstrom@3:633/10 to All on Mon Jun 15 06:55:42 2026
    Lynn McGuire wrote this screed in ALL-CAPS:

    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:

    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    That looks to me to be " 1343222440" plus 4 empty strings.

    This is currently planned for C++28.

    Sounds screwy to me, given that adjacent quotes strings are
    combined into one, a feature I use a lot..

    A new error or to initialize the string array properly ?

    Got a URL ?

    --
    667:
    The neighbor of the beast.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Mon Jun 15 14:34:26 2026
    On 6/13/2026 7:52 PM, Keith Thompson wrote:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    On 2026-06-12 18:35, Lynn McGuire wrote:
    ...
    I used the F2C translator with many changes on my part. F2C does not
    handle Fortran character strings very well at all.

    Here is my Fortran code:

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    Here is my translated C++ code from my F2C:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB"
    "VSTB" "TCTB" "TCTB";

    Is it possible that one of your changes broke something? That would not
    be an accurate translation of the fortran code for any version of C, not
    even the oldest.

    No, the original f2c does this -- and it appears to be correct.
    I think f2c is designed to generate C code that behaves the same
    way as its input Fortran code, *not* to generate C code that's
    expected to be maintained in that form. A tool to do the latter
    could be very useful, but probably much harder to implement.

    I was able to turn the above Fortan into a complete working program.
    (Without the print, f2c eliminated the declaration of IBNK, since
    it was unused.)

    program lynn

    character*4 IBNK (9)
    DATA (IBNK (I), I = 1, 9)
    1 / 'CPTB', 'VPTB', 'LVTB', 'LHTB', 'STTB', 'VSTB',
    * 'VSTB', 'TCTB', 'TCTB' /

    print '(a)', IBNK(2)
    end

    When I compile it with gfortran, the output is:

    VPTB

    which is what I expected. When I feed to f2c version 20200916, the
    generated C code includes the following:

    static char ibnk[4*9] = "CPTB" "VPTB" "LVTB" "LHTB" "STTB" "VSTB" "VSTB"
    "TCTB" "TCTB";

    But it also includes this:

    do_fio(&c__1, ibnk + 4, (ftnlen)4);

    which looks (to me) like correct code to extract and print the
    characters "VPTB" from the char array ibnk.

    f2c might sensibly have used a single string literal "CPTBVPTBLVTBLHTBSTTBVSTBVSTBTCTBTCTB", but that could run into
    problems with line length.

    I haven't been able (after not trying very hard) to get the generated
    C code to compile and execute correctly.

    I *think* the Fortran declaration of IBNK specifies that it contains
    the consecutive characters "CPTBVPTBLVTBLHTBSTTBVSTBVSTBTCTBTCTB",
    and any code that extracts a 4-character element has to know the
    dimensions. The generated C code appears to do the same thing,
    correctly as far as I can tell.

    The problem is that the generated C code is very un-C-like, and even
    more un-C++-like -- and apparently Lynn was (quite understandably)
    thrown off by the odd use of string literal concatenation. Changing
    this automatically generated C written with a strong Fortran accent
    to C++ code using std::string almost has to be done manually, while
    referring back to the input Fortran code to understand how it's
    supposed to behave. Doing that reliably requires a strong knowledge
    of both Fortran and C++, and even so is likely to be error-prone.

    Thanks for the analysis! I have been writing Fortran 66 (IV) code since
    1975, Fortran 77 code since 1989, and C++ since 1999.

    Yes, I would like to automate my conversion of the Fortran like C
    strings to std::string but I am a quarter of the way through with my conversion of my 800,000 lines of F77 code. I am not sure that
    performing a deep dive of F2C's conversion of Fortran character strings
    to C's character strings would be worth it for me for time savings as
    F2C is a multiple pass translator based on the F77 Unix compiler.

    And, I am converting the string writes to typesafe code in C++ which is
    worth quite a bit to me in code safety. I really hate it when a program
    is crashing and goes to an error statement and does a hard crash there
    in a call to printf or sprintf. Using type safe code in C++ stops hard crashes.

    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Mon Jun 15 14:11:45 2026
    Chris Ahlstrom <OFeem1987@teleworm.us> writes:
    Lynn McGuire wrote this screed in ALL-CAPS:

    On 6/12/2026 2:58 AM, Bonita Montero wrote:
    Am 12.06.2026 um 01:43 schrieb Lynn McGuire:

    Hi, is a comma required for initializing a std::string array?
    This compiles without error on Visual C++ 2015:
    std::string strings [5] = { " " "1" "3432" "2244" "0" };

    That looks to me to be " 1343222440" plus 4 empty strings.

    This is currently planned for C++28.

    Sounds screwy to me, given that adjacent quotes strings are
    combined into one, a feature I use a lot..

    Bonita didn't say what "this" is, and I found no evidence that any
    relevant change is planned. (Bonita is in my killfile, so I may have
    missed something.)

    A new error or to initialize the string array properly ?

    Got a URL ?

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Mon Jun 15 23:04:04 2026
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:

    And, I am converting the string writes to typesafe code in C++ which is >worth quite a bit to me in code safety. I really hate it when a program
    is crashing and goes to an error statement and does a hard crash there
    in a call to printf or sprintf. Using type safe code in C++ stops hard >crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally
    any function using printf/scanf style format strings) for a couple of
    decades.

    Avoiding printf/snprintf using C++ '<<' redirection requires signficantly
    more source _and_ object code than using the *printf family functions.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lynn McGuire@3:633/10 to All on Mon Jun 15 18:18:14 2026
    On 6/15/2026 6:04 PM, Scott Lurndal wrote:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:

    And, I am converting the string writes to typesafe code in C++ which is
    worth quite a bit to me in code safety. I really hate it when a program
    is crashing and goes to an error statement and does a hard crash there
    in a call to printf or sprintf. Using type safe code in C++ stops hard
    crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally
    any function using printf/scanf style format strings) for a couple of decades.

    Avoiding printf/snprintf using C++ '<<' redirection requires signficantly more source _and_ object code than using the *printf family functions.

    old Fortran code:

    WRITE(OUFILE,22)(I,W(NWF+I),I=1,M)
    22 FORMAT (//4X,'I',7X,'=(I)',10X,'I',7X,'F(I)',10X,'I',7X,'F(I)', 10X,'I',7X,'F(I)',10X,'I',7X,'F(I)'//5(I5,E17.8))

    new C++ code:

    outwri ("\n\n I =(I) I F(I) I
    F(I) I F(I) I F(I)\n");
    i8__1 = m;
    for (i = 1; i <= i8__1; ++i) {
    str = asString (i, 5) + asString (w[nwf + i - 1], 17, 8);
    if ((i % 5) == 0)
    str += "\n";
    }
    outwri (str);

    Neither of my calculation engines are what I would call petite:
    05/24/2026 05:25 PM 4,242,880 chemtran.dll
    05/24/2026 05:25 PM 11,830,208 designii.dll

    My asString functions (17 at the moment) enforce type safety for me. I
    care way more about type safety than I do program size.

    My small calculation engine is 200,000 lines of F77 code and 10,000
    lines of C++ code.

    My large calculation engine is 700,000 lines of F77 code and 50,000
    lines of C++ code.

    That is good to know about g++ as I may use it in the future.

    Lynn


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Mon Jun 15 17:05:08 2026
    scott@slp53.sl.home (Scott Lurndal) writes:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:
    And, I am converting the string writes to typesafe code in C++ which is >>worth quite a bit to me in code safety. I really hate it when a program >>is crashing and goes to an error statement and does a hard crash there
    in a call to printf or sprintf. Using type safe code in C++ stops hard >>crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally
    any function using printf/scanf style format strings) for a couple of decades.

    Are you referring to the warnings that gcc issues for mismatched
    printf arguments (only if the format string is a literal), or is
    there some other feature I don't know about?

    [...]

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Jun 16 10:31:02 2026
    On 16/06/2026 02:05, Keith Thompson wrote:
    scott@slp53.sl.home (Scott Lurndal) writes:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:
    And, I am converting the string writes to typesafe code in C++ which is
    worth quite a bit to me in code safety. I really hate it when a program >>> is crashing and goes to an error statement and does a hard crash there
    in a call to printf or sprintf. Using type safe code in C++ stops hard
    crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally
    any function using printf/scanf style format strings) for a couple of
    decades.

    Are you referring to the warnings that gcc issues for mismatched
    printf arguments (only if the format string is a literal), or is
    there some other feature I don't know about?


    I don't know of anything beyond the format warnings in gcc, but it is
    quite possible to use them in connection with non-literal format strings.

    A typical case is when you are doing internationalisation. You might
    have something like :

    printf(gettext("Document %s page %i", doc_name, page_no));

    Since "gettext" is a function, gcc does not know the actual string at
    compile time, so it can't check it against the argument types. The user
    might pick a different language at runtime and there would be a
    different string.

    However, all the translations of "Document %s page %i" need to have the
    same format conversion specifiers, because these have to match up with
    the printf arguments. So it is enough to do the checking against a
    single string :

    printf_gettext("Document %s page %i", doc_name, page_no);

    with (untested) :

    __attribute__((format (printf, 1, 3)))
    static inline
    int printf_gettext(const char * s, ...) {
    va_list args;
    va_start(args, s);
    vfprintf(gettext(s), args);
    va_end(args);
    }

    That of course does not cover all uses of printf a non-literal format
    string, but it covers a lot.



    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jun 16 09:31:35 2026
    On Tue, 16 Jun 2026 10:31:02 +0200
    David Brown <david.brown@hesbynett.no> gabbled:
    On 16/06/2026 02:05, Keith Thompson wrote:
    scott@slp53.sl.home (Scott Lurndal) writes:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:
    And, I am converting the string writes to typesafe code in C++ which is >>>> worth quite a bit to me in code safety. I really hate it when a program >>>> is crashing and goes to an error statement and does a hard crash there >>>> in a call to printf or sprintf. Using type safe code in C++ stops hard >>>> crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally
    any function using printf/scanf style format strings) for a couple of
    decades.

    Are you referring to the warnings that gcc issues for mismatched
    printf arguments (only if the format string is a literal), or is
    there some other feature I don't know about?


    I don't know of anything beyond the format warnings in gcc, but it is
    quite possible to use them in connection with non-literal format strings.

    A typical case is when you are doing internationalisation. You might
    have something like :

    Another case is when doing safe output of strings so embedded % codes can't cause a security issue. ie:

    printf("%s",some_unverified_string)


    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Jun 16 12:31:31 2026
    On 16/06/2026 11:31, boltar@caprica.universe wrote:
    On Tue, 16 Jun 2026 10:31:02 +0200
    David Brown <david.brown@hesbynett.no> gabbled:
    On 16/06/2026 02:05, Keith Thompson wrote:
    scott@slp53.sl.home (Scott Lurndal) writes:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:
    And, I am converting the string writes to typesafe code in C++
    which is
    worth quite a bit to me in code safety.ÿ I really hate it when a
    program
    is crashing and goes to an error statement and does a hard crash there >>>>> in a call to printf or sprintf.ÿ Using type safe code in C++ stops
    hard
    crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally >>>> any function using printf/scanf style format strings) for a couple of
    decades.

    Are you referring to the warnings that gcc issues for mismatched
    printf arguments (only if the format string is a literal), or is
    there some other feature I don't know about?


    I don't know of anything beyond the format warnings in gcc, but it is
    quite possible to use them in connection with non-literal format strings.

    A typical case is when you are doing internationalisation.ÿ You might
    have something like :

    Another case is when doing safe output of strings so embedded % codes can't cause a security issue. ie:

    printf("%s",some_unverified_string)


    No, that is different - the format string /is/ a literal here. It is
    "%s", and can be checked by gcc. The unverified string can contain
    percent characters, but they are not interpreted in any way.


    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jun 16 15:12:56 2026
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    scott@slp53.sl.home (Scott Lurndal) writes:
    Lynn McGuire <lynnmcguire5@gmail.com> writes:
    On 6/13/2026 7:52 PM, Keith Thompson wrote:
    And, I am converting the string writes to typesafe code in C++ which is >>>worth quite a bit to me in code safety. I really hate it when a program >>>is crashing and goes to an error statement and does a hard crash there >>>in a call to printf or sprintf. Using type safe code in C++ stops hard >>>crashes.

    gcc (and g++) have supported type-safe printf/snprintf (and optionally
    any function using printf/scanf style format strings) for a couple of
    decades.

    Are you referring to the warnings that gcc issues for mismatched
    printf arguments (only if the format string is a literal)

    Yes.

    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From red floyd@3:633/10 to All on Tue Jun 16 14:16:43 2026

    I think what Scott is getting at is...

    some_function()
    {
    // build a format string here
    const char *format;

    format = <some expression that builds a format string>

    printf(format, <some value list>);
    }

    isn't type checked.



    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Jun 17 08:24:29 2026
    On 16/06/2026 23:16, red floyd wrote:

    I think what Scott is getting at is...


    I don't think Scott was saying that, but sure, you are absolutely right.
    gcc (and clang, and possibly other compilers) can't do any checking in
    cases like this. The printf checks don't provide a fully general
    type-checked printf. But they /do/ provide checks that cover by far the
    most common uses of printf (with literal format strings), and with a bit
    of effort they cover most uses of non-literal format strings. They
    don't cover the kind of thing you show below, but that type of construct
    is relatively rare.

    some_function()
    {
    ÿÿ // build a format string here
    ÿÿ const char *format;

    ÿÿ format = <some expression that builds a format string>

    ÿÿ printf(format, <some value list>);
    }

    isn't type checked.




    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)