Skip to content

Give an option to remove 'using namespace' #7760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 27, 2018
Merged

Conversation

deepikabhavnani
Copy link

@deepikabhavnani deepikabhavnani commented Aug 10, 2018

Description

DO NOT MERGE

I have created this PR to get input from all teams for solution to namespace issue.
Purpose:

  1. To give an option to remove "using namespace" with MBED_NO_NAMESPACE macro
  2. Move all classes in Mbed OS inside mbed namespace. Addition of existing classes inside mbed namespace breaks compatibility, hence below code should be added to maintain compatibility.
// Added "using" for backwards compatibility
#ifndef MBED_NO_NAMESPACE
using mbed::<Classname>;
#endif

List of all classes to be moved to mbed namespace. Feel free to add to the list or comment below if you know of any class additions.

[ ] All Block Devices
[ ] Filesystem's

Related: #6684

Pull request type

[ ] Fix
[ ] Refactor
[ ] Target update
[ ] Feature
[X] Breaking change

CC @geky @bridadan @dlfryar @0xc0170 @pan- @kjbracey-arm

@kjbracey
Copy link
Contributor

kjbracey commented Aug 13, 2018

Looks conceptually good to me. Is the intent then that application code would either define this MBED_NO_NAMESPACE globally or on a per-file basis before including mbed header files?

Little bit doubtful about the name - it's more MBED_NO_USING, but then that sounds weird. MBED_NO_GLOBAL_NAMESPACE?

There is another possible alternative approach. You could do what the C++ library does and make it so that #include <mbed> doesn't do the using, but #include <mbed.h> does.

That is a pattern I've not seen outside the standard C++ library, but given that it's there it shouldn't be totally unfamiliar. But it doesn't match our use of .h for all other header files, and not sure what other problems lack of .h would cause.

Maybe #include of some other name that omits the using - "mbed_os.h"? That approach doesn't cover backwards compatibility with people directly including ObservingBlockDevice.h though.

@pan-
Copy link
Member

pan- commented Aug 13, 2018

There is another possible alternative approach. You could do what the C++ library does and make it so that #include doesn't do the using, but #include <mbed.h> does.

I like the idea but I fear it confuses some of our developers. Our codebase itself is not consistent with the practice.

For the name, like @kjbracey-arm I think it should be changed. MBED_NO_NAMESPACE feels like it removes namespace. I can think of few names: MBED_NO_GLOBAL_USING_DIRECTIVE or MBED_NO_GLOBAL_USING_NAMESPACE.

What's the path going forward ? Is there a plan to set this macro by default ? It may be worthwhile to think of how components are mapped into namespaces as we may require more than just the mbed namespace.

@deepikabhavnani
Copy link
Author

deepikabhavnani commented Aug 13, 2018

Is the intent then that application code would either define this MBED_NO_NAMESPACE globally or on a per-file basis before including mbed header files?

Can leave that to application. It should work both ways, if we make sure mbed-os compiles with flag enabled globally. Default we cannot enable it, but adding it to CI or not will be question.

For the name, like @kjbracey-arm I think it should be changed. MBED_NO_NAMESPACE feels like it removes namespace. I can think of few names:MBED_NO_GLOBAL_USING_DIRECTIVE or MBED_NO_GLOBAL_USING_NAMESPACE.

Yes , good names are appreciated. MBED_NO_GLOBAL_USING_NAMESPACE / MBED_NO_GLOBAL_USING_DIRECTIVE 👍

#include doesn't do the using, but #include <mbed.h> does.

Agree with @pan- it will be confusing, Also as you mentioned it will not be backward compatible we should avoid that solution.

@bmcdonnell-ionx
Copy link
Contributor

As a user, I agree with not dropping the .h extension from your header file names. AFAIK it's not a convention outside the C++ library.

Default we cannot enable it

How about for Mbed OS 6.0?

Or, zooming out, why is mbed.h necessary or desirable at all? For instance, you don't #include <TheWholeCppLibrary.h>; you #include just the headers you need. Why is it a good thing to have a single header that makes the entire OS/lib interface visible?

@pan- said previously (#5679 (comment)):

From my perspective, the issue in that case is the use of mbed.h directly in os/production code. It is not designed for that usage and unsafe regards to name collision by design. The sole and only viable solution is to not use it in code that needs to be name collision free.

Unfortunately uses of mbed.h are not properly documented which lead developers to use it in the wrong context. That would be nice to have a clear documentation bloc explaining what mbed.h is as well as how and where it should be used.

About the changes proposed, I personally believe that even if mbed-os.h solves the name collision issue it is not a facility that should be used in production code except if we want to encourage build time increases.

@kjbracey
Copy link
Contributor

Or, zooming out, why is mbed.h necessary or desirable at all?

My understanding is that it's desirable for "simplicity" - simple apps just include "mbed.h". Same basic argument as putting every single folder on the include path, and putting everything in the global namespace.

Also, possibly some of the core built-in stuff doesn't have as obviously clear "what to include" rules as "Thread.h" for Thread, so I guess it mops up a bunch of miscellaneous stuff - types, error codes etc, giving us leeway to restructure a bit.

I would say it should not be used in any OS or library header files, so that the name pollution isn't forced on application code.

@@ -15,7 +15,10 @@
*/

#include "events/mbed_shared_queues.h"
#include "mbed.h"

#ifdef MBED_CONF_RTOS_PRESENT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see similar changes in this PR that could be separated from adding new config (changes in events files at least)? As I expect with this config change to touch only mbed or std namespace (add it ,remove it).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing namespace i.e building mbed-os with "-DMBED_NO_GLOBAL_USING_DIRECTIVE" results in build failures as 'mbed.h' added here will not add RTOS / Mbed namespace in cpp files as well.

This cleanup "i.e. add only required namespace/header file" is needed for removal of namespace to work. I can add it as separate PR, and make this PR to be dependent on that.

@bmcdonnell-ionx
Copy link
Contributor

@kjbracey-arm,

I would say it should not be used in any OS or library header files, so that the name pollution isn't forced on application code.

I absolutely agree.

Assuming you do keep it, please also document in appropriate places (when it becomes true) that application code doesn't need to #include "mbed.h".

@deepikabhavnani
Copy link
Author

I would say it should not be used in any OS or library header files, so that the name pollution isn't forced on application code.

👍 Removing mbed.h here - #7864

@deepikabhavnani
Copy link
Author

Dependent on #7864 #8002 #8008

Copy link
Member

@bulislaw bulislaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@0xc0170
Copy link
Contributor

0xc0170 commented Nov 26, 2018

@deepikabhavnani All storage PR landed, or still waiting for some here?

@deepikabhavnani
Copy link
Author

@deepikabhavnani All storage PR landed, or still waiting for some here?

Review from storage team is pending as well

@dannybenor
Copy link

@offirko can you please review?

Copy link
Contributor

@offirko offirko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no remarks, LGTM.

@bulislaw
Copy link
Member

All the PRs need to be engineering ready (marked as "needs: CI") by the end of the day (Austin time). Otherwise it won't make 5.11 and will need to come in the next release (5.12 for features, 5.11.1 for fixes and new platforms).

…mespace

Macro guard `MBED_NO_GLOBAL_USING_DIRECTIVE` is added around namespace, to avoid
polluting users namespace.
@deepikabhavnani
Copy link
Author

Rebased

@cmonr
Copy link
Contributor

cmonr commented Nov 26, 2018

CI started.

@cmonr cmonr added the risk: G label Nov 26, 2018
Adding new modules inside the namespace could be breaking change for existing code base
hence add `using namespace::class` for classes newly added to mbed namespace to maintian
backwards compatibility.

MBED_NO_GLOBAL_USING_DIRECTIVE is added to remove auto-addition of namespace
Macro guard `MBED_NO_GLOBAL_USING_DIRECTIVE` is added around namespace, to avoid
polluting users namespace.
@deepikabhavnani
Copy link
Author

@cmonr - Fixed for failing device. Needs CI restart

@cmonr
Copy link
Contributor

cmonr commented Nov 27, 2018

#7760 (comment)

I like it. So fast, didn't even realize this had a problem.

CI restarted.

@mbed-ci
Copy link

mbed-ci commented Nov 27, 2018

Test run: SUCCESS

Summary: 4 of 4 test jobs passed
Build number : 10
Build artifacts
Build logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.