Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is this class variable initialization legal ?

47 views
Skip to first unread message

Lynn McGuire

unread,
Apr 27, 2020, 11:42:03 PM4/27/20
to
Is this class variable initialization legal ?

class ExcelSelection
{
public:
std::string selectionSpreadsheetName = "";
std::string selectionSheetName = "";
std::string selectionBeginRow = "";
std::string selectionBeginColumn = "";
std::string selectionEndRow = "";
std::string selectionEndColumn = "";
int isRange = false;
public:
};

My C++ expert on staff says no. I say yes since Visual C++ 2015 likes it.

Thanks,
Lynn

Ian Collins

unread,
Apr 27, 2020, 11:53:30 PM4/27/20
to
What does your "expert" claim is wrong with it?

By the way, you don't need to initialise the strings.

--
Ian.

Alf P. Steinbach

unread,
Apr 28, 2020, 12:55:19 AM4/28/20
to
The explicit initializations of the strings have the same effect as the
default initialization, so it's verbosity that IMO is best removed.

The `isRange` member is evidently intended to be a `bool`, not an `int`,
so that's a likely typo (although it could be a thinko, but anyway
better fix).

It's generally a good idea to adopt a special naming convention for
non-`static` data members. Boost uses an underscore suffix. I use prefix
`m_` because that supports auto-complete in various editors.

However, for a simple pure data class with just public data members and
nothing else, I don't use such prefixes, but then instead of `class` and
`public:` I just use `struct`. To my mind that communicates the intended
usage much more clearly. It's also shorter, and it's idiomatic (so much
that the Holy Standard™ defines terms like `standard-layout struct`).

Whether explicit namespace qualification is good or bad or doesn't
matter is debatable and most people have strong opinions. I see such
qualifications as being very much in violation of the Don't Repeat
Yourself principle, i.e. this is decidedly not DRY code. To improve the
DRY-ness I would put that class in a namespace with a `using
std::string` in that namespace.

namespace excel {
using std::string;

struct Selection
{
string spreadsheet_name;
string sheet_name;
string begin_row;
string begin_column;
string end_row;
string end_column;
bool is_range = false;
};
} // namespace excel

Apart from these clarity issues the code is technically OK as of C++11
and later.


- Alf

Jorgen Grahn

unread,
Apr 28, 2020, 1:47:40 AM4/28/20
to
On Tue, 2020-04-28, Lynn McGuire wrote:
> Is this class variable initialization legal ?
>
> class ExcelSelection
> {
> public:
> std::string selectionSpreadsheetName = "";
> std::string selectionSheetName = "";
> std::string selectionBeginRow = "";
> std::string selectionBeginColumn = "";
> std::string selectionEndRow = "";
> std::string selectionEndColumn = "";
> int isRange = false;
> public:
> };

To add to the style advice you didn't ask for:

- I'd remove the "selection" prefix from the ExcelSelection members.
People use redundancy in names a lot, but it confuses me: I read it
in this case as a second level of selection within the selection,
and have to stop and read again more carefully[0].
(Alf also removed them in his rewrite, but didn't comment on
it I think.)

- I'd wrap (row, column) pairs and call them a Position, or CellName,
or something (I'm not so familiar with Excel). That kind of
refactoring is cheap and IME very helpful.

struct ExcelSelection {
std::string spreadsheetName;
std::string sheetName;
Position begin;
Position end;
bool isRange = false;
};

/Jorgen

[0] I get the same mental effect when I read the phrase "The
Department of Redundancy Department", which someone used
recently over in alt.folklore.computers.

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Juha Nieminen

unread,
Apr 28, 2020, 2:36:36 AM4/28/20
to
It's perfectly legal in C++11 and newer. It's not valid syntax in C++98.

Unfortunately many a C++ "expert" out there still lives in the pre-C++11
era.

On a side note, initializing an std::string object with "" is rather useless
because the default constructor of std::string already initializes it to be
an emptry string. (In fact, it's actually potentially more efficient to just
let it be initialized by the default constructor. It might be possible that
a compiler will optimize that useless ="" initialization away, but unlikely,
as I doubt that compilers have been made aware of what the std::string
constructors actually do internally.)

Juha Nieminen

unread,
Apr 28, 2020, 2:42:49 AM4/28/20
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> Whether explicit namespace qualification is good or bad or doesn't
> matter is debatable and most people have strong opinions. I see such
> qualifications as being very much in violation of the Don't Repeat
> Yourself principle, i.e. this is decidedly not DRY code. To improve the
> DRY-ness I would put that class in a namespace with a `using
> std::string` in that namespace.

That's exactly as silly as saying that you should do this:

#define f for

in order to avoid repeating the "or" part needlessly. Don't repeat yourself!

I am almost 100% certain that if the standardization committee had originally
decided to prepend all standard library names with "std_" (and reserved that
prefix for use by the standard library), you would not be advising people
to write

#define string std_string

in order to avoid writing that "std_" part. So why are you advising them
against writing "std::"? What's the problem there? The two colons? Is that
the problem here?

Jorgen Grahn

unread,
Apr 28, 2020, 4:01:39 AM4/28/20
to
On Tue, 2020-04-28, Juha Nieminen wrote:
> Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>> Whether explicit namespace qualification is good or bad or doesn't
>> matter is debatable and most people have strong opinions. I see such
>> qualifications as being very much in violation of the Don't Repeat
>> Yourself principle, i.e. this is decidedly not DRY code. To improve the
>> DRY-ness I would put that class in a namespace with a `using
>> std::string` in that namespace.
>
> That's exactly as silly as [...]

I don't want to be part of the argument (not this rerun of it, anyway)
but I note that in larger code bases I've seen at work, in various
organizations, people generally keep the std:: prefix, Juha-style.

/Jorgen

Lynn McGuire

unread,
Apr 28, 2020, 2:38:40 PM4/28/20
to
This is 500,000 lines of C++ code. We put the std:: in on purpose. We
have another code library that has a string class also. Avoids confusion.

Thanks,
Lynn

Lynn McGuire

unread,
Apr 28, 2020, 2:40:40 PM4/28/20
to
Thanks !

I like explicitly initializing variables since I have been so burned in
the past. Just an old Fortran hacker writing C++.

Lynn

Lynn McGuire

unread,
Apr 28, 2020, 6:08:29 PM4/28/20
to
I agree with your selection prefix for the class variables and have
removed them. They were the old instance variables in the code before I
added this class.

Structs are so C code. This is a C++ forum.

Thanks !

Lynn

Lynn McGuire

unread,
Apr 28, 2020, 6:13:27 PM4/28/20
to
My thoughts exactly. We went through an enormous amount of work adding
std:: all over our 500,000 lines of C++ code.

Thanks !

Lynn

Ian Collins

unread,
Apr 28, 2020, 7:04:31 PM4/28/20
to
What did your "expert" claim is wrong with the code?

--
Ian.

Lynn McGuire

unread,
Apr 28, 2020, 8:43:53 PM4/28/20
to
The string and int initializations were not allowed. Others in the
above postings said those came about in the C++2011 spec.

Lynn

Ian Collins

unread,
Apr 28, 2020, 8:47:58 PM4/28/20
to
Okay, so Juha's guess was on the money!

--
Ian.


Lynn McGuire

unread,
Apr 28, 2020, 9:54:18 PM4/28/20
to
I am sorry that I did not make that clear.

And I got hung out by my Open Watcom pre C++2011 compiler which refused
the class variable initializations. So I got to put in a #ifndef. Lovely.

class ExcelSelection
{
public:
#ifndef __WATCOMC__
std::string spreadsheetName = "";
std::string sheetName = "";
std::string beginRow = "";
std::string beginColumn = "";
std::string endRow = "";
std::string endColumn = "";
bool isRange = false;
#else
std::string spreadsheetName;
std::string sheetName;
std::string beginRow;
std::string beginColumn;
std::string endRow;
std::string endColumn;
bool isRange;
#endif
public:
};

Thanks !

Lynn


Ian Collins

unread,
Apr 28, 2020, 10:06:13 PM4/28/20
to
Ah, well you could remove all of the string initialisers and just put
the bool inside the ifdef. You could make it more generic by using

#if __cplusplus < 201103L

to support pre-C++11 compilers.

But you are still left with the need to selectively initialise members
in constructors.

--
Ian.

David Brown

unread,
Apr 29, 2020, 3:42:14 AM4/29/20
to
A better idea would be decide to write pre-C++11 code, or post-C++11
code. Mixing the two is just going to get piles of conditional code and
duplications like this. These particular initialisations match the
defaults for the types - what happens when they don't? Are you going to
have a conditional for having some members initialised and some not, and
then conditionals in the constructors to do the member initialisation
for C++03 mode? The code will be a complete mess.

It's better to have:

#if __cplusplus < 201103L
#error Your compiler is too old, or your settings are wrong!
#endif

If the code really has to work pre-C++11, then write it /all/ in
pre-C++11, and use "g++ -std=c++03 -Wpedantic" to check.

Juha Nieminen

unread,
Apr 29, 2020, 4:15:37 AM4/29/20
to
Lynn McGuire <lynnmc...@gmail.com> wrote:
> I like explicitly initializing variables since I have been so burned in
> the past. Just an old Fortran hacker writing C++.

If a class has a default constructor, and what it does is what you want,
then it's unnecessary to initialize it explicitly.

In most cases initializing an instance of such a class explicitly is not
harmful, but as mentioned, in this case it may actually cause a very minor
amount of overhead because now the std::string objects will be initialized
with a char*, which the constructor needs to go through, while the
default constructor (ie. the one that takes no parameters) will probably
do something that avoids that.

The difference is extremely small and probably not even worth "optimizing",
but I don't really see a reason to have the useless ="" initializations
there anyway, so the optimization, no matter how small, is effectively
free.
0 new messages