Access specifier as part of member declarations

88 views
Skip to first unread message

hamza...@me.com

unread,
Jan 15, 2018, 2:15:01 PM1/15/18
to ISO C++ Standard - Future Proposals
The current access specifier system makes a lot of sense due to the common practice of writing out the interface for a class separately in a header file. Header files tend to be written for potential users of the class: public stuff at the top (since that’s what users will be using), then protected and finally private. Being able to write “public:” once at the top and have all following declarations made automatically public is very convenient.

With the proposed module system, it becomes feasible for small projects to adopt the single file approach and forego writing a separate file for an interface. With the single file approach, class members won’t necessarily be grouped by access (because it’s no longer being written just for a user). However it’s fairly cumbersome and error prone to frequently change access types with the current access specifier system, and it adds a lot of noise to the code.

E.g:

class MyClass {
public:
void somethingPublic() { }
private:
void somethingPrivate() { }
public:
void anotherPublicThing() { }
};

I propose being able to write that as:

class MyClass {
public void somethingPublic() { }
private void somethingPrivate() { }
public void anotherPublicThing() { }
};

This has the added benefit of being familiar to people coming from other languages (Java, C#, Swift, lots of others).

As a purely additive change, I don’t see this breaking any existing code.

Nevin Liber

unread,
Jan 15, 2018, 2:25:23 PM1/15/18
to std-pr...@isocpp.org
On Mon, Jan 15, 2018 at 1:15 PM, <hamza...@me.com> wrote:
With the proposed module system, it becomes feasible for small projects to adopt the single file approach and forego writing a separate file for an interface. With the single file approach, class members won’t necessarily be grouped by access (because it’s no longer being written just for a user). However it’s fairly cumbersome and error prone to frequently change access types with the current access specifier system, and it adds a lot of noise to the code.

E.g:

    class MyClass {
        public:
             void somethingPublic() { }
        private:
             void somethingPrivate() { }
        public:
             void anotherPublicThing() { }
    };

Or, written w/o extra newlines:

    class MyClass {
        public: void somethingPublic() { }
        private: void somethingPrivate() { }
        public: void anotherPublicThing() { }
    };
 
I propose being able to write that as:

    class MyClass {
        public void somethingPublic() { }
        private void somethingPrivate() { }
        public void anotherPublicThing() { }
    };

This seems to boil down to saying that ':' adds a lot of noise to the code.
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  +1-847-691-1404

hamza...@me.com

unread,
Jan 15, 2018, 3:26:59 PM1/15/18
to ISO C++ Standard - Future Proposals
Writing the specificer on the same line with a colon is an error-prone abuse of syntax; it isn’t immediately obvious that the specifier applies to more than just the declaration that it shares a line with.

Nevin Liber

unread,
Jan 15, 2018, 3:35:27 PM1/15/18
to std-pr...@isocpp.org
On Mon, Jan 15, 2018 at 2:26 PM, <hamza...@me.com> wrote:
Writing the specificer on the same line with a colon is an error-prone abuse of syntax; it isn’t immediately obvious that the specifier applies to more than just the declaration that it shares a line with.

Given this is supposed to be a "purely additive change" (your words), what is the access for things declared afterwards?

It seems very error-prone to change the access based upon an accidental presence/absence of a colon.
-- 

hamza...@me.com

unread,
Jan 15, 2018, 3:48:34 PM1/15/18
to ISO C++ Standard - Future Proposals
It’d work like it does in every other language: following declarations will be unaffected.

It’s no more error-prone than omitting braces from an if statement changing a multi-line block into a single line.

if (thing)
imInTheIf();
iLookLikeIAmButImNotReally();

Jonathan Coe

unread,
Jan 15, 2018, 3:55:16 PM1/15/18
to std-pr...@isocpp.org
This seems like a probable source of subtle and frustrating errors for very little real gain.

> --
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
> To post to this group, send email to std-pr...@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e0e88414-a7da-40ad-a6f4-9ab73d69c72c%40isocpp.org.

Tony V E

unread,
Jan 15, 2018, 5:03:24 PM1/15/18
to Standard Proposals
On Mon, Jan 15, 2018 at 3:48 PM, <hamza...@me.com> wrote:
It’d work like it does in every other language: following declarations will be unaffected.

ay, there's the rub.

In every other language, per-line is the _only_ way to do it.  In C++ you would allow people to mix things:

public:
    int x;
    private int y;
    int z;

Now add a bunch of comments, etc, between those lines, and you start wonder about the access of z.

The current way encourages you to separate public from private. What's would the benefit be of the new way?

Do you want code that's more "per-subject"?

    private int thing;
    pubic setThing(int);

    private double otherThing;
    public setOtherThing(double);

    private string title;
    public setTitle(string);

This would allow you to more easily add/remove features from your class.
But guess what - if you have multiple features in your class, your class is probably too big. Single Responsibility.


--
Be seeing you,
Tony

Nicol Bolas

unread,
Jan 15, 2018, 5:05:19 PM1/15/18
to ISO C++ Standard - Future Proposals, hamza...@me.com
On Monday, January 15, 2018 at 2:15:01 PM UTC-5, hamza...@me.com wrote:
The current access specifier system makes a lot of sense due to the common practice of writing out the interface for a class separately in a header file. Header files tend to be written for potential users of the class: public stuff at the top (since that’s what users will be using), then protected and finally private. Being able to write “public:” once at the top and have all following declarations made automatically public is very convenient.

With the proposed module system, it becomes feasible for small projects to adopt the single file approach and forego writing a separate file for an interface. With the single file approach, class members won’t necessarily be grouped by access (because it’s no longer being written just for a user). However it’s fairly cumbersome and error prone to frequently change access types with the current access specifier system, and it adds a lot of noise to the code.

I contest the motivation here.

There are many C++ types that already put everything in a "single file". Template types have to do this as a matter of course. And yet, there is no real desire on the part of programmers to randomly interleave public and private methods. Or at least, not to the extent you're talking about.

Indeed, such interleaving reduces the ease of understanding the code and benefits only the writer of that code. Since code is read more often than it is written, you should adopt a writing style that makes it easy for readers of the code to understand it. Interleaving isn't doing that.

Modules will be written as much for users as for the writer of the class.

As a purely additive change, I don’t see this breaking any existing code.

As Nevin pointed out, being "purely additive" is a problem. It means that not typing a `:` can radically change the nature of code. As it currently stands, not typing that `:` is a compile error. With what you want, it wouldn't be anymore. Your code will just work... until it doesn't.

No. If you want each member to have an access class explicitly specified, then do that with the existing syntax. Either way, you have to be consistent about it to get the advantages you claim exist.

Tony V E

unread,
Jan 15, 2018, 5:09:48 PM1/15/18
to Standard Proposals
public:
   Constructor(int);
private
    int x;
    int y;
    int z;

//whoops!




No. If you want each member to have an access class explicitly specified, then do that with the existing syntax. Either way, you have to be consistent about it to get the advantages you claim exist.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.

To post to this group, send email to std-pr...@isocpp.org.

Scott Dolim

unread,
Jan 15, 2018, 7:43:20 PM1/15/18
to ISO C++ Standard - Future Proposals
Probably it would be better to treat the first such single-member access specifier declaration as the start of an "every declaration must have its own access specifier" region, until the next public:, private:, or protected: is seen.  I mean, since you've told the compiler you're in a C# kind of mood, might as well stick with it till your mood changes.  The compiler will helpfully hold you to it ("missing required access specifier on line 20").  People coming from C#/Java/etc are used to that already, anyway.  That said, the benefits of this do not seem overwhelming.  (I'd rather see "public:" in C# and Java, really.  My eyes get tired of reading "public" so many times.)

To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.

To post to this group, send email to std-pr...@isocpp.org.

Alberto Barbati

unread,
Jan 16, 2018, 4:27:46 AM1/16/18
to ISO C++ Standard - Future Proposals
Il giorno lunedì 15 gennaio 2018 23:03:24 UTC+1, Tony V E ha scritto:


On Mon, Jan 15, 2018 at 3:48 PM, <hamza...@me.com> wrote:
It’d work like it does in every other language: following declarations will be unaffected.

ay, there's the rub.

In every other language, per-line is the _only_ way to do it.  In C++ you would allow people to mix things:

public:
    int x;
    private int y;
    int z;

 
Who said we should allow to mix things? This is a new proposal, so we can decide differently. Indeed, I say that as soon as the compiler detect the use of one style of access specifiers, the rest of the class declaration must abide to that style. This would greatly reduce the probability of mistakes, while giving the freedom to choose between the two styles.

Just my 2 eurocent,

Nicol Bolas

unread,
Jan 16, 2018, 10:07:38 AM1/16/18
to ISO C++ Standard - Future Proposals


On Tuesday, January 16, 2018 at 4:27:46 AM UTC-5, Alberto Barbati wrote:
Il giorno lunedì 15 gennaio 2018 23:03:24 UTC+1, Tony V E ha scritto:


On Mon, Jan 15, 2018 at 3:48 PM, <hamza...@me.com> wrote:
It’d work like it does in every other language: following declarations will be unaffected.

ay, there's the rub.

In every other language, per-line is the _only_ way to do it.  In C++ you would allow people to mix things:

public:
    int x;
    private int y;
    int z;

 
Who said we should allow to mix things?

The OP, who said that this was "a purely additive change". It can't be purely additive without the ability to mix things. 

hamza...@me.com

unread,
Jan 16, 2018, 10:26:17 AM1/16/18
to ISO C++ Standard - Future Proposals
I didn’t phrase that particularly well. I think disallowing mixing is a good solution to the problems mentioned above.

Zhihao Yuan

unread,
Jan 16, 2018, 10:46:32 AM1/16/18
to std-pr...@isocpp.org

UTC Time: January 15, 2018 10:03 PM

The current way encourages you to separate public from private. What's would the benefit be of the new way?

There is a huge benefit -- in a "patch" generated by
"diff", now you can clearly see what does the change
mean without including a context of growing length.
Local reasoning needs to apply to "patch" as well.


--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
_______________________________________________


Jake Arkinstall

unread,
Jan 16, 2018, 10:51:23 AM1/16/18
to std-pr...@isocpp.org
I don't support the proposal given that a near-as-damnit version can be used with the addition of a colon. I always group my public, protected, private methods up regardless of the language I'm using, and that's fairly standard practice, so all this would do is add noise. I'm not exactly against the proposal, but as I can't see any benefits I cannot support it. I'm also biased because I originally started out with PHP, C#, Java, and other languages that use this form, and C++ allowing grouping like this was like a breath of fresh air. We should do more of that.

In fact I wouldn't much mind the ability to do it with inline, const, constexpr, static, template, noexcept etc. Not to a level where it gets ugly (which is easy to get to, and nesting might be controversial), but I also find myself grouping these naturally anyway - and when was the last time you wrote a class with just one const method, or just one method with a given template?


On 16 Jan 2018 15:07, "Nicol Bolas" <jmck...@gmail.com> wrote:
 It can't be purely additive without the ability to mix things. 

Why? If it works as it currently does for classes that use "public:" etc, but you can create new classes that strictly use the "new" approach, then it is still only additive - surely? Allowing mixing would made debugging awkward:

class FreeAsInSpeech{
public // whoops. Forgot the colon.
        void thing();
        void another_thing(); // not visible outside A, breaks code needing it.
};

struct ControllingCachedCalculatorThing{
protected // whoops. Forgot the colon.
        int x;
        int y; // oh no. Exposed to the outside world. Goodbye stability.
public:
        void set_y(int new_y){
               if(ridiculous_condition(new_y)){
                      y = new_y;
                      update();
               }
        }
        void update();
};

class FortKnox{
        public: std::string try_get_info(...); //whoops. Accidental colon.
        std::string get_top_secret_info(); // amazing security setup. 10/10. Great job.
};

I'm no fan of allowing hard-to-detect problems to arise from a single character.

Jake Arkinstall

unread,
Jan 16, 2018, 10:58:13 AM1/16/18
to std-pr...@isocpp.org


On 16 Jan 2018 15:46, "Zhihao Yuan" <z...@miator.net> wrote:

UTC Time: January 15, 2018 10:03 PM

The current way encourages you to separate public from private. What's would the benefit be of the new way?

There is a huge benefit -- in a "patch" generated by
"diff", now you can clearly see what does the change
mean without including a context of growing length.
Local reasoning needs to apply to "patch" as well.

... okay, excellent point. Though I have to say that a patch that requires modifying access specifiers is less of a patch and more of a structural modification. I'd expect to see this at a new minor version of an application rather than as a patch, so I'm not convinced that this is common.

hamza...@me.com

unread,
Jan 16, 2018, 11:04:07 AM1/16/18
to ISO C++ Standard - Future Proposals
Those are some good points; I understand that the style isn’t going to liked by everyone. However I think your last example (the FortKnox one) is actually an argument for the proposal. The “almost but not quite” method mentioned a few times (current access specifier system but on the same line) is dangerous because makes it look like you’re applying the access spec to a single declaration but really you aren’t.

hamza...@me.com

unread,
Jan 16, 2018, 11:09:51 AM1/16/18
to ISO C++ Standard - Future Proposals
Regarding patches, I recall seeing similar arguments for using the static keyword per definition when possible instead of an unnamed namespace. Easier for grep and diff and whatever.
Reply all
Reply to author
Forward
0 new messages