Tuesday, April 28, 2020

Digest for comp.lang.c++@googlegroups.com - 15 updates in 3 topics

Lynn McGuire <lynnmcguire5@gmail.com>: Apr 27 10:41PM -0500

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 <ian-news@hotmail.com>: Apr 28 03:53PM +1200

On 28/04/2020 15:41, Lynn McGuire wrote:
> public:
> };
 
> My C++ expert on staff says no. I say yes since Visual C++ 2015 likes it.
 
What does your "expert" claim is wrong with it?
 
By the way, you don't need to initialise the strings.
 
--
Ian.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 28 06:55AM +0200

On 28.04.2020 05:41, Lynn McGuire wrote:
> public:
> };
 
> My C++ expert on staff says no.  I say yes since Visual C++ 2015 likes it.
 
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 <grahn+nntp@snipabacken.se>: Apr 28 05:47AM

On Tue, 2020-04-28, Lynn McGuire wrote:
> 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 <nospam@thanks.invalid>: Apr 28 06:36AM

> public:
> };
 
> My C++ expert on staff says no. I say yes since Visual C++ 2015 likes it.
 
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 <nospam@thanks.invalid>: Apr 28 06:42AM

> 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 <grahn+nntp@snipabacken.se>: Apr 28 08:01AM

On Tue, 2020-04-28, Juha Nieminen wrote:
>> 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
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Lynn McGuire <lynnmcguire5@gmail.com>: Apr 28 01:38PM -0500

On 4/28/2020 3:01 AM, Jorgen Grahn wrote:
> 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
 
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 <lynnmcguire5@gmail.com>: Apr 28 01:40PM -0500

On 4/28/2020 1:36 AM, Juha Nieminen wrote:
> 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.)
 
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 <lynnmcguire5@gmail.com>: Apr 28 05:08PM -0500

On 4/28/2020 12:47 AM, Jorgen Grahn wrote:
 
> [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.
 
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 <lynnmcguire5@gmail.com>: Apr 28 05:13PM -0500

On 4/28/2020 1:42 AM, Juha Nieminen wrote:
 
> 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?
 
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 <ian-news@hotmail.com>: Apr 29 11:04AM +1200

On 29/04/2020 06:40, Lynn McGuire wrote:
 
> Thanks !
 
> I like explicitly initializing variables since I have been so burned in
> the past. Just an old Fortran hacker writing C++.
 
What did your "expert" claim is wrong with the code?
 
--
Ian.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 28 09:50AM -0700

>> programs. That number is closer to 0%.
 
> Can you explain why? I can't immediately think of a reason why no
> C program would be valid C++ without modification [...]
 
There are a lot of ways that C code doesn't work as C++. If a C
program violates even one of these ways it is no longer a valid C++
program. As programs get larger, and as more third-party libraries
are used, the chance of using one of the non-C++ forms gets bigger;
asymptotically the ratio of C++-valid C programs to C programs goes
to zero.
 
I'm sure you know many of the ways that C code can fail to be
valid C++, but probably there are some you haven't thought of.
Certainly there are ones I didn't think of until just recently
when I ran a piece of C code through a C++ compiler. Some of
the obvious problems:
 
use of C++ keywords
use of _Bool
use of restrict
string literal not const
conversion of void* without a cast
 
Several items related to enumerated types:
 
mismatch of type chosen for enumerated types
overflow in implicit constant conversion
invalid conversion (basic integer type to enumerated type)
 
Some C constructs that are either not supported or not completely
supported in C++:
 
designated initializers
compound literals
anonymous structs
parameter declarators (related to variable length arrays)
uninitialized const (forward/"tentative" definition)
 
Some C++ constraints are not satisfied by the C code:
 
narrowing conversion
comparison of distinct pointer types (eg, int(*)[3] == int(*)[])
no user-provided default constructor (I'm not sure what
caused this error but the C code compiles without
problem)
 
Some error messages I didn't understand (I didn't spend time
trying to track these down; it's possible they are cascaded
errors):
 
redefinition of type (?)
name redeclared as a different kind of symbol (?)
 
All of the above errors were produced compiling a single C
translation unit, encompassing about 3000 lines of source
(include non-system header includes). The C++ compiles were done
using g++, as C++14, and again as C++17 (the C++17 was done as
a sanity check to see if some particular errors might have
disappeared; AFAICS none did).
 
Besides the problems that show up as compile errors, there are
semantic differences. These incompatibilities are worse than the
ones that get compiler warnings, as there may silently produce
different behavior or be undefined behavior. I haven't tried to
do an exaustive search for these, but there are at least three:
 
inline functions - semantic differences between C and C++.
unions - C allows type punning, C++ does not.
"common initial sequence" - the rules for which members
belong to the common initial sequence are (I think)
the same in C and C++, but how those members may be
used is different in C and C++. In particular, some
cases that have defined behavior in C are undefined
behavior in C++.
 
Of course, it is possible to avoid all of these incompatibilities
if one is determined to do so. But people who are writing C
don't do that, partly because it's a big pain in the ass to try
to do it, and partly because there is no particular incentive to
do so. There isn't anything especially exotic about the C code
I used for my C++ test compilations; probably some of the error
conditions shown above are a product of less common usages, but
certainly not all of them were. Given the number and variety of
differences between the two languages, the chance of any given C
program of any size also being a valid C++ program seems rather
remote. But don't take my word for it - take any open source C
program and try compiling it as C++. What results do you see?
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 28 10:14AM -0700

> of heat, over and over again ... but as I see it, pretty much
> everyone has a C compiler and a C++ compiler, and will compile
> their C code with the former and their C++ code with the latter.
 
Speaking for myself, I am not bothered at all that C and C++ are
different languages. In fact I think it's good that they are, and
they should be free to go their separate ways. It would be better
for both languages to give up on the idea of "harmonizing" C and
C++, which is a pointless fiction (or worse, a way of making C be
more like C++, without C++ changing in any significant way). I
would much rather see two clearly delineated choice points than
some sort of muddled middle ground. If and when I want to take
the C++ view, I write C++; if and when I want to take the C view,
I write C. I see no reason to confuse the issue by pretending
there is some sort of significant common ground between them.
Thirty years ago there was, but now there isn't, and it's time to
move on.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 28 06:44AM -0700

>> available on Amazon for $144.
 
> Thanks for your comments. I would probably use FreeBSD
> rather than Linux for that.
 
You're welcome. I didn't mean to suggest that Linux is the only
viable choice. I have a fair amount of experience using Linux
(and also other systems) to do routing/networking, and am happy to
recommend it, but FreeBSD (where I have very little experience)
may also be fine.
 
> I'm trying to avoid Amazon.
 
I wasn't recommending Amazon, just providing a convenient point of
reference and one that is a known quantity.
 
> One alternative I've found is https://www.bhphotovideo.com
 
Great, I will try to take a look.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: