Re: [boost] What to do with platform defining 'null' as preprocessor symbol?

Jan Hudec wrote:
At work we develop, among others, for Bada. The system library provided is unfortunately somewhat flaky. A tell-tale sign is, that it's native API headers define lowercase 'null' as preprocessor symbol expanding to 0.
Another one, huh? Did they learn that trick from Microsoft?
Unfortunately boost uses identifier 'null'. [snip] Would it make sense to rename those identifiers and avoid that name like boost avoids 'min' and 'max'?
Boost doesn't avoid "min" and "max" but encloses them in parentheses to prevent preprocessor expansion. "null" could be treated similarly, though some may prefer to choose a different identifier. (At least there isn't an algorithm named "null"!) You'll need to find all the places where "null" occurs and file Trac tickets to get things fixed. If you supply patches against trunk, they are more likely to be applied. If you can apply the patches and run the tests yourself against several compilers on different platforms, you could send a summary reply to this thread with the Trac issues and the results of your testing. Then, someone might even submit all of your patches in one go. _____ Rob Stewart robert.stewart@sig.com Software Engineer using std::disclaimer; Dev Tools & Components Susquehanna International Group, LLP http://www.sig.com ________________________________ IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

[Robert Stewart]
Boost doesn't avoid "min" and "max" but encloses them in parentheses to prevent preprocessor expansion. "null" could be treated similarly, though some may prefer to choose a different identifier.
Parentheses defend against function-like macros, but not against object-like macros. STL

On 8/23/2012 12:59 PM, Stewart, Robert wrote:
Jan Hudec wrote:
At work we develop, among others, for Bada. The system library provided is unfortunately somewhat flaky. A tell-tale sign is, that it's native API headers define lowercase 'null' as preprocessor symbol expanding to 0.
Another one, huh? Did they learn that trick from Microsoft?
Apple's contributed more than there share with 'nil', 'check', ...
Unfortunately boost uses identifier 'null'. [snip] Would it make sense to rename those identifiers and avoid that name like boost avoids 'min' and 'max'?
Boost doesn't avoid "min" and "max" but encloses them in parentheses to prevent preprocessor expansion. "null" could be treated similarly, though some may prefer to choose a different identifier. (At least there isn't an algorithm named "null"!)
You'll need to find all the places where "null" occurs and file Trac tickets to get things fixed. If you supply patches against trunk, they are more likely to be applied.
If you can apply the patches and run the tests yourself against several compilers on different platforms, you could send a summary reply to this thread with the Trac issues and the results of your testing. Then, someone might even submit all of your patches in one go.
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places. Jeff

On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On Aug 23, 2012 9:59 PM, "Eric Niebler" <eric@boostpro.com> wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
Perhaps, pragmas like push/pop_macro could help on compilers that support it?

On Thu, Aug 23, 2012 at 22:09:06 +0400, Andrey Semashev wrote:
On Aug 23, 2012 9:59 PM, "Eric Niebler" <eric@boostpro.com> wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
Anybody using boost is probably used to reasonable C++ practices and uses 'NULL' or 'nullptr' and not funky platform-specific nonsense like 'null'. So from this point of view I'd be more inclined to undefining it or erroring out if it's defined and let the under undefine it by hand (well, any reasonable user will IMHO do it in user_config.hpp anyway).
Perhaps, pragmas like push/pop_macro could help on compilers that support it?
Unfortunately I don't think gcc 4.5.0 does. -- Jan 'Bulb' Hudec <bulb@ucw.cz>

On Aug 24, 2012 10:18 PM, "Jan Hudec" <bulb@ucw.cz> wrote:
On Thu, Aug 23, 2012 at 22:09:06 +0400, Andrey Semashev wrote:
Perhaps, pragmas like push/pop_macro could help on compilers that
support
it?
Unfortunately I don't think gcc 4.5.0 does.
I don't know of 4.5.0 but it looks like 4.5.4 does: http://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Push_002fPop-Macro-Pragmas.html#...

On 8/24/12 1:58 AM, Eric Niebler wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
It's been a long standing issue that I can't seem to find a resolution for: Fusion's use of nil. What can we do about it? Nothing? Do we just let the user deal with it themselves (e.g. by #undef'ing). I am somehow being compelled to succumb to the pressure. Mac folks have been pleading for years now to rename struct nil to something else. Unfortunately, it's part of the API: http://tinyurl.com/c3k7fgw Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com

On 24/08/2012 01:09, Joel de Guzman wrote:
On 8/24/12 1:58 AM, Eric Niebler wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
It's been a long standing issue that I can't seem to find a resolution for: Fusion's use of nil. What can we do about it? Nothing? Do we just let the user deal with it themselves (e.g. by #undef'ing). I am somehow being compelled to succumb to the pressure. Mac folks have been pleading for years now to rename struct nil to something else. Unfortunately, it's part of the API: http://tinyurl.com/c3k7fgw
Name it nil_, and if 'nil' is not defined, provide a typedef named nil as well.

On 24/08/12 19:09, Mathias Gaunard wrote:
On 24/08/2012 01:09, Joel de Guzman wrote:
On 8/24/12 1:58 AM, Eric Niebler wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
It's been a long standing issue that I can't seem to find a resolution for: Fusion's use of nil. What can we do about it? Nothing? Do we just let the user deal with it themselves (e.g. by #undef'ing). I am somehow being compelled to succumb to the pressure. Mac folks have been pleading for years now to rename struct nil to something else. Unfortunately, it's part of the API: http://tinyurl.com/c3k7fgw
Name it nil_, and if 'nil' is not defined, provide a typedef named nil as well.
Would namespaces help in any way?

On 24/08/12 19:26, Bjorn Reese wrote:
On 2012-08-24 11:10, Jookia wrote:
Would namespaces help in any way?
Preprocessor macros do not respect namespaces.
Ah, yeah. But I was kind of thinking that instead of writing 'nil', you'd write 'fusion::nil'. Maybe I'm missing something important.

On 2012-08-24 11:27, Jookia wrote:
Ah, yeah. But I was kind of thinking that instead of writing 'nil', you'd write 'fusion::nil'. Maybe I'm missing something important.
Assuming that you have this macro: #define nil 0 Then 'fusion::nil' will be changed by the preprocessor to 'fusion::0'.

On 24/08/12 19:38, Bjorn Reese wrote:
On 2012-08-24 11:27, Jookia wrote:
Ah, yeah. But I was kind of thinking that instead of writing 'nil', you'd write 'fusion::nil'. Maybe I'm missing something important.
Assuming that you have this macro:
#define nil 0
Then 'fusion::nil' will be changed by the preprocessor to 'fusion::0'.
Really? Wow. I thought it was only for 'words' rather than tokens. My bad. The only other idea that I'd have would to have an alternate name for 'nil'. Which has probably been discussed, making this entire post redundant. Sorry.

On Fri, 24 Aug 2012 07:09:35 +0800, Joel de Guzman wrote:
On 8/24/12 1:58 AM, Eric Niebler wrote:
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
It's been a long standing issue that I can't seem to find a resolution for: Fusion's use of nil. What can we do about it? Nothing? Do we just let the user deal with it themselves (e.g. by #undef'ing). I am somehow being compelled to succumb to the pressure. Mac folks have been pleading for years now to rename struct nil to something else. Unfortunately, it's part of the API: http://tinyurl.com/c3k7fgw
I would just use #define nil nil as a sanity check and call it done. If the symbol is already defined, compilation error (or at least warning on overly permissive compilers). The symbol will be need to be undefined in between the inclusion of the two libraries. Workarounds like nil_ and (min)(...) just perpetuate the problem. Fix the root problem rather than treating the symptom indefinitely. Otherwise, where is the line drawn? Even if you can't provide a transparent fix (such as defining nil as a constant and min/max as functions), the backwards compatibility argument fails in the long run. The amount of effort required to make the necessary changes to existing code will eventually be outweighed by the effort to implement workarounds put into new code (as well as educate everyone that they are necessary)--especially in cases like these which can mostly be emulated in a way that causes most existing code to work. Regards, Paul Mensonides

On 8/23/2012 7:09 PM, Joel de Guzman wrote:
On 8/24/12 1:58 AM, Eric Niebler wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
It's been a long standing issue that I can't seem to find a resolution for: Fusion's use of nil. What can we do about it? Nothing? Do we just let the user deal with it themselves (e.g. by #undef'ing). I am somehow being compelled to succumb to the pressure. Mac folks have been pleading for years now to rename struct nil to something else. Unfortunately, it's part of the API: http://tinyurl.com/c3k7fgw
Searching the dozens of Mac Frameworks used in our projects, I get two hits for 'nil': - objc.h #ifndef nil #define nil __DARWIN_NULL #endif and - MacTypes.h #ifndef nil #define nil NULL #endif We have a pretty large and old code base whose 'nil' usage, is well nil;-). So as I've mentioned to Joel before, I'd hate to see time spent on modifying fusion use of 'nil'. Using BOOST_PREVENT_MACRO_SUBSTITUTION certainly doesn't help with code clarity, and I've not checked if it works with names beyond function names: types, variables, arguments, ... Jeff

On 8/23/2012 1:58 PM, Eric Niebler wrote:
On 8/23/2012 1:42 PM, Jeff Flinn wrote:
Might it not be better to provide some platform specific config file(s) that undef offending macro names. In the case of nil in fusion, I'd hate to see a loss in clarity because of some bad platform practice. I've been able to address these issues by #undef'ing in just a few places.
Bad idea, IMO. Boost shouldn't be messing with things defined in 3rd party headers, especially platform headers. #including a boost header shouldn't change the meaning of existing code, or make valid platform code invalid. The same reason went into the Boost min/max guidelines and Herculean effort to bring our codebase into compliance with them.
As Stephan L mentions, BOOST_PREVENT_MACRO_SUBSTITUTION doesn't appear to alleviate issues with object macros. As you said the effort to deal with min/max was herculean. min/max was pretty apparent with such prevalent use. How do we root out other cases of platform macro abuse and deal with them? Jeff
participants (11)
-
Andrey Semashev
-
Bjorn Reese
-
Eric Niebler
-
Jan Hudec
-
Jeff Flinn
-
Joel de Guzman
-
Jookia
-
Mathias Gaunard
-
Paul Mensonides
-
Stephan T. Lavavej
-
Stewart, Robert