How to test C++98 compatibility?

25 views
Skip to first unread message

melcher....@googlemail.com

unread,
May 6, 2023, 5:44:17 AM5/6/23
to fltk.coredev
I think I have a great solution for our limited callback functionality that is compatible with C++98, but how can I test that? It uses some extensive and unreadable macros and requires __VA_ARGS__, which was only "standardised" in C++99, but most older compiler "just had it".

Anyway, the solution is a header-only file that generates more complex callbacks on the fly, so simply not including the header would keep full compatibility.

My question is, is there any way to test if my code would compile on old compilers? Or should I just merge it, and we will wait for feedback?

 - Matthias

Albrecht Schlosser

unread,
May 6, 2023, 8:26:14 AM5/6/23
to fltkc...@googlegroups.com
On 5/6/23 11:44 'melcher....@googlemail.com' via fltk.coredev wrote:
I think I have a great solution for our limited callback functionality that is compatible with C++98,

What new capabilities would it provide? Can we see code or documentation?


but how can I test that? It uses some extensive and unreadable macros and requires __VA_ARGS__, which was only "standardised" in C++99, but most older compiler "just had it".

I don't like macros and "unreadable macros" even less. If your solution uses non-C++98-standard features we should probably not include it.

Anyway, the solution is a header-only file that generates more complex callbacks on the fly, so simply not including the header would keep full compatibility.

OK, header-only sounds a bit better. Nobody needs to compile it. But then we can't have a test suite and example (demo) programs unless we make sure that they are compiled only optionally or dependent on C++ standard version.

My question is, is there any way to test if my code would compile on old compilers?

Setting the C++ standard to compile wouldn't help if you know already that it's not C++ 98 compliant.

Docker can be helpful to test old system environments w/o installing an entire VM or such. But that wouldn't help with any "exotic" platforms that don't have this feature and that we don't test explicitly...


Or should I just merge it, and we will wait for feedback?

We should at least see the code and vote whether it should be included. IMHO such non-standard features require a vote by devs.

Mo_Al_

unread,
May 6, 2023, 12:20:20 PM5/6/23
to fltk.coredev
If the header file is standalone, i.e. doesn't use any fltk headers, you can try using compiler-explorer:

You can find many compilers including g++4, you can also pass `-std=c++98 -pedantic-errors` in the compiler options field.
Unfortunately the oldest msvc compiler is v19. So even if it compiles with gcc, you can't be sure it compiles with msvc. For that you might need a virtual machine running some old version of windows. You can find visual studio 6 images as well. 

imacarthur

unread,
May 8, 2023, 6:14:47 AM5/8/23
to fltk.coredev
How far back do we want to go?

Greg maybe still has MSVC-6 for example?

On the gcc side, I think anything since about gcc-4 should be fine with that, IIRC.
Older gcc versions might be more dubious, but they would most likely be from before the various gcc C++ ABI changes, so unlikely to still be used anyway...

As regards the gcc C++ binary changes: As I recall it (i.e. I didn't check this!) the C++ ABI changed at the transition from gcc-2.95 to gcc-3, and then again at about gcc-3.3 or thereabouts. It's been pretty stable since and generally compatible going forwards.
There were some systems locked into the older ABI though - I think the BeOS / Haiku folks were locked into the old gcc-2.95 ABI (thought I think Haiku added a compatibility layer later to use newer tools) and vxWorks-5 was tied to a "gcc-2.96" ABI, which I think was their port of the last supported 2.95 version. (VxWorks-6 shipped with gcc-4.3, and that was "long ago" now anyway.)

Other than that, I'd assume most platforms have tools "modern enough" to make it work... anything that does not is likely to be pretty niche (like emulating the ABI of the Apple Newton, say) so we'd likely never be able to test it anyway.

Greg Ercolano

unread,
May 8, 2023, 8:33:19 AM5/8/23
to fltkc...@googlegroups.com

On 5/8/23 03:14, imacarthur wrote:

On Saturday, 6 May 2023 at 10:44:17 UTC+1 Matt wrote:
My question is, is there any way to test if my code would compile on old compilers? Or should I just merge it, and we will wait for feedback?

How far back do we want to go?
Greg maybe still has MSVC-6 for example?

    VS7 is the furthest back I go for 32bit builds.

melcher....@googlemail.com

unread,
May 8, 2023, 9:32:43 AM5/8/23
to fltk.coredev
Thanks for all the input. Very helpful! This is in reference to this PR: https://github.com/fltk/fltk/pull/729 . The macros in question are very unreadable, but the unwrapped some is at the bottom of the file. Basically, I am emulating Lambdas for callbacks using old-style C++ and macros. 


A test program is in the examples folder:


melcher....@googlemail.com

unread,
May 8, 2023, 9:58:56 AM5/8/23
to fltk.coredev
Ok, so I used https://godbolt.org (awesome!) to compile with any meaningful compiler down to Spark, Webassembly, ESP32, and llvm for Commodore C46. Lowest gcc available is 4.8.5. MSVC does not go low at all. The code does compile a test macro on each and every one of them. Only if I set `-std=c++98` and pedantic, I will get an error: anonymous variadic macros were introduced in C99. Not sure if that is acceptable. I can of course rewrite this to use a trailing number for number of arguments... : `FL_FUNCTION_CALLBACK_3(btn, something, int, a, 3, int, b, 4, int, c, 5)`

Albrecht Schlosser

unread,
May 9, 2023, 3:33:16 PM5/9/23
to fltkc...@googlegroups.com
On 5/8/23 15:58 'melcher....@googlemail.com' via fltk.coredev wrote:
Ok, so I used https://godbolt.org (awesome!) to compile with any meaningful compiler down to Spark, Webassembly, ESP32, and llvm for Commodore C46. Lowest gcc available is 4.8.5.

Every dev should bookmark this (I did already). In some questionable areas this might be useful.


MSVC does not go low at all. The code does compile a test macro on each and every one of them. Only if I set `-std=c++98` and pedantic, I will get an error: anonymous variadic macros were introduced in C99. 

... as expected with '-pdantic'.


Not sure if that is acceptable.

This kind of callbacks is a new feature. If someone insists on using ancient compilers they should not use this **new** feature. That's it.

IMHO acceptable, yes.


I can of course rewrite this to use a trailing number for number of arguments... : `FL_FUNCTION_CALLBACK_3(btn, something, int, a, 3, int, b, 4, int, c, 5)`

This would be an interesting change because it would make sure that you assign the correct number of arguments (triplets) for every macro. Should be considered, IMHO. Even better if it also increases compatibility...

melcher....@googlemail.com

unread,
May 10, 2023, 4:06:57 AM5/10/23
to fltk.coredev
Unfortunately we can't have it both. The compiler throws an error es soon as it sees the ellipsis (...). But I could disable the varargs version if fl_attr.h determines a really old compiler.

imacarthur

unread,
May 10, 2023, 4:30:06 AM5/10/23
to fltk.coredev
On Wednesday, 10 May 2023 at 09:06:57 UTC+1 Matt wrote:
Albrecht Schlosser schrieb am Dienstag, 9. Mai 2023 um 21:33:16 UTC+2:
On 5/8/23 15:58 'melcher...' via fltk.coredev wrote:
I can of course rewrite this to use a trailing number for number of arguments... : `FL_FUNCTION_CALLBACK_3(btn, something, int, a, 3, int, b, 4, int, c, 5)`
This would be an interesting change because it would make sure that you assign the correct number of arguments (triplets) for every macro. Should be considered, IMHO. Even better if it also increases compatibility...

Unfortunately we can't have it both. The compiler throws an error es soon as it sees the ellipsis (...). But I could disable the varargs version if fl_attr.h determines a really old compiler.

FWIW, I'm inclined towards the variadic macro solution.
Maybe, as Albrecht suggested earlier, we can include something in the docs. to the effect of "If you are using an older compiler that does not support variadic macros, this feature will not be available, so in that case do not use it!"

I'd assume anyone choosing to use an old compiler toolchain is doing so for a reason, probably knows what they are doing, and may well be running on ancient hardware that has limited capabilities anyway...

melcher....@googlemail.com

unread,
May 10, 2023, 4:56:38 AM5/10/23
to fltk.coredev

Good point. I will add a note in the docs to not include the header file for pre C99 compilers.

Albrecht Schlosser

unread,
May 10, 2023, 8:18:17 AM5/10/23
to fltkc...@googlegroups.com
On 5/10/23 10:30 imacarthur wrote:
On Wednesday, 10 May 2023 at 09:06:57 UTC+1 Matt wrote:
Albrecht Schlosser schrieb am Dienstag, 9. Mai 2023 um 21:33:16 UTC+2:
On 5/8/23 15:58 'melcher...' via fltk.coredev wrote:
I can of course rewrite this to use a trailing number for number of arguments... : `FL_FUNCTION_CALLBACK_3(btn, something, int, a, 3, int, b, 4, int, c, 5)`
This would be an interesting change because it would make sure that you assign the correct number of arguments (triplets) for every macro. Should be considered, IMHO. Even better if it also increases compatibility...

Unfortunately we can't have it both. The compiler throws an error es soon as it sees the ellipsis (...).

I didn't suggest to have both versions. My thoughts were about **changing** the macros to ones with '_n' that represents the number of callback function arguments so the user can get feedback if they are using the wrong number of macro arguments (e.g. missing one part of a triplet, etc.).


But I could disable the varargs version if fl_attr.h determines a really old compiler.

No, please don't do that. It would make user code that works on newer compilers fail on those older compilers anyway. It's better to have only one macro implementation for clarity.


FWIW, I'm inclined towards the variadic macro solution.

Hmm, why? Just for my curiosity.

Anyway, I'm not against it, I could live with both a variadic and a "counted arguments" version. But I also see that the variadic macro solution would be more elegant.


Maybe, as Albrecht suggested earlier, we can include something in the docs. to the effect of "If you are using an older compiler that does not support variadic macros, this feature will not be available, so in that case do not use it!"

I'd assume anyone choosing to use an old compiler toolchain is doing so for a reason, probably knows what they are doing, and may well be running on ancient hardware that has limited capabilities anyway...

Yep, I agree.

Reply all
Reply to author
Forward
0 new messages