bugGNU gettext - Bugs: bug #64006, *printf() defines break C++ builds...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #64006: *printf() defines break C++ builds (specifically Qt)

Submitter:  Pierre Ossman <cendossm>
Submitted:  Thu 06 Apr 2023 08:52:37 AM UTC
   
 
Category:  Programmer interface Severity:  3 - Normal
Item Group:  None Status:  Fix Released
Privacy:  Public Assigned to:  haible
Open/Closed:  Closed

Jump to the original submission

Sun 01 Dec 2024 04:35:45 PM UTC, comment #11: 

The fix is contained in gettext 0.23.

Bruno Haible <haible>
Group administrator
Thu 28 Nov 2024 08:00:21 PM UTC, comment #10: 

The commit https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=commitdiff;h=e4a1c66c1ddb05fa67f00678bda9ec24af5e4de6 provides a fix, in the following sense:

  • In C++ mode, where possible, overriding the *printf functions is now done through inline functions instead of through C macros.


  • The "where possible" restriction applies to mingw and MSVC, which define some *printf functions as inline functions in a header file. Such inline functions can ONLY be overridden through C macros. In particular, this affects 'asprintf' on mingw.


  • In order to nevertheless avoid a conflict with Qt, you can define a macro _INTL_NO_DEFINE_MACRO_ASPRINTF, that will inhibit that macro definition.
Bruno Haible <haible>
Group administrator
Tue 13 Jun 2023 12:16:33 PM UTC, comment #9: 

For c++11 and later, variadic templates can be used:


#if __cplusplus >= 201103L
template<typename ... Args>
void asprintf(const char* x, Args ... args)
{
    libintl_asprintf(x, args ... );
}
#else
%define asprintf libintl_asprintf
#endif


Stefan BrĂ¼ns <stefanbruens>
Fri 02 Jun 2023 08:13:52 AM UTC, comment #8: 

Oh, I completely misunderstood then. I thought it was both or neither. Thank you for that clarification!

Pierre Ossman <cendossm>
Fri 02 Jun 2023 08:06:20 AM UTC, comment #7: 


> it would be very helpful for our programmers to make sure that they actually use the position markers where things need to be translated.


The programmer does not need to use the position markers. The programmer can use just "bla %s blabla %s", and it's the translator who introduces the position markers when reordering.

Bruno Haible <haible>
Group administrator
Fri 02 Jun 2023 07:40:53 AM UTC, comment #6: 

Oh, I just realised that once we fix up this support, it would be very helpful for our programmers to make sure that they actually use the position markers where things need to be translated.

Are there any tools that can assist with enforcing that?

(sorry for the comment spam)

Pierre Ossman <cendossm>
Fri 02 Jun 2023 07:39:28 AM UTC, comment #5: 

Great. That at least slightly reduced the issue from a current bug that needs to be urgently addressed, to an eventually required feature.

Thank you for the insight!

Pierre Ossman <cendossm>
Fri 02 Jun 2023 12:09:54 AM UTC, comment #4: 


> if neither the programmer nor the translator use the position markers, will gettext implicitly add them in any scenario?


No, gettext will not add %1$ or such. It returns what the translator has provided in the PO file, assuming it has been checked through "msgfmt -c".

There is no tool that tests whether a translator has used this syntax, and frankly we don't want to have such a tool. It would be bad to tell the translators "you cannot reorder arguments, as required for your language, because one of the target platforms of the application is Windows and the programmer has not been able rectify this platform's printf deficiencies."

Bruno Haible <haible>
Group administrator
Thu 01 Jun 2023 02:57:45 PM UTC, comment #3: 


comment #2:

> The reason is that translators need the freedom to reorder arguments within format strings, see https://www.gnu.org/software/gettext/manual/html_node/c_002dformat-Flag.html
>
> If a system's printf implementation does not support this, the output will be non-intelligible to users.
>


Yes, that is a big problem. But if neither the programmer nor the translator use the position markers, will gettext implicitly add them in any scenario?

Pierre Ossman <cendossm>
Thu 01 Jun 2023 01:43:57 PM UTC, comment #2: 


> I'm wondering why there *printf() replacements are unconditionally included, with no way to turn them off?


They are included on platforms that need them, in particular on native Windows.

The reason is that translators need the freedom to reorder arguments within format strings, see https://www.gnu.org/software/gettext/manual/html_node/c_002dformat-Flag.html

If a system's printf implementation does not support this, the output will be non-intelligible to users.

> we have convenience functions that take format strings in many places


You have to look whether the format string interpreter actually supports the %1$, %2$, etc. syntax.

Bruno Haible <haible>
Group administrator
Thu 06 Apr 2023 08:56:36 AM UTC, comment #1: 

I'm wondering why there *printf() replacements are unconditionally included, with no way to turn them off?

Does gettext have assumptions that require the POSIX behaviour? Or did you figure that everyone needs the argument position feature to make life easier for the translators?

If it's the former, then we probably break that assumption in many places, as we have convenience functions that take format strings in many places. :/

Pierre Ossman <cendossm>
Thu 06 Apr 2023 08:52:37 AM UTC, original submission:  

gettext tries to redirect the various *printf() functions to its own implementation if the platform version doesn't comply to the POSIX behaviour.

Unfortunately, it does this using #define:s, which isn't very compatible with C++ and the namespacing there. It is more careful about C++ when handling the various *gettext() functions, but not here.

A specific scenario where this breaks is when using Qt's QString::asprintf():

D:/a/tigervnc/tigervnc/vncviewer/vncconnection.cxx:1727:24: error: 'libintl_asprintf' is not a member of 'QString'
 1727 |   infoText += QString::asprintf(_("Security method: %s\n"), rfb::secTypeName(m_securityType));
      |                        ^~~~~~~~
make[2]: * [vncviewer/CMakeFiles/vncviewer.dir/build.make:255: vncviewer/CMakeFiles/vncviewer.dir/vncconnection.cxx.obj] Error 1

More complete build log here:

https://github.com/CendioOssman/tigervnc/actions/runs/4626832263/jobs/8184028650

Pierre Ossman <cendossm>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by stefanbruens (Posted a comment)
  • -email is unavailable- added by haible (Updated the item)
  • -email is unavailable- added by cendossm (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2024-12-01 haible StatusFixed Fix Released
    2024-11-28 haible Assigned toNone haible
        Open/ClosedOpen Closed
    2024-11-28 haible StatusConfirmed Fixed
    2023-04-06 haible StatusNone Confirmed

    Back to the top

    Powered by Savane 3.14-f13d.
    Corresponding source code