Tuesday, November 5, 2013

comp.lang.c++ - 26 new messages in 6 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* ODB C++ ORM 2.3.0 released, adds schema evolution support - 1 messages, 1
author
http://groups.google.com/group/comp.lang.c++/t/6e7bb1631f34f291?hl=en
* Inject std namespace into main() - 3 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/5a1fbdc0a014b400?hl=en
* Why string's c_str()? [Overloading const char *()] - 9 messages, 5 authors
http://groups.google.com/group/comp.lang.c++/t/e6c9d55b4c332550?hl=en
* String and interfacing with functions using char* - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/a7d848d28878a317?hl=en
* Compiler for Linux - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/c1bd2a41213c7ef1?hl=en
* C and C++ - 10 messages, 9 authors
http://groups.google.com/group/comp.lang.c++/t/0c5cd0246395d2ed?hl=en

==============================================================================
TOPIC: ODB C++ ORM 2.3.0 released, adds schema evolution support
http://groups.google.com/group/comp.lang.c++/t/6e7bb1631f34f291?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 30 2013 4:59 am
From: Boris Kolpackov


I am pleased to announce the release of ODB 2.3.0.

ODB is an open source object-relational mapping (ORM) system for C++. It
allows you to persist C++ objects to a relational database without having
to deal with tables, columns, or SQL and without manually writing any of
the mapping code.

Major new features in this release:

* Support for database schema evolution, including automatic schema
migration, immediate and gradual data migration, as well as soft
object model changes (ability to work with multiple schema versions
using the same C++ classes).

For a quick showcase of this functionality see the Changing Persistent
Classes section in the Hello World Example chapter:

http://www.codesynthesis.com/products/odb/doc/manual.xhtml#2.9

* Support for object sections which provide the ability to split data
members of a persistent C++ class into independently loaded/updated
groups.

* Support for automatic mapping of C++11 enum classes.

A more detailed discussion of these features can be found in the following
blog post:

http://www.codesynthesis.com/~boris/blog/2013/10/30/odb-2-3-0-released/

For the complete list of new features in this version see the official
release announcement:

http://www.codesynthesis.com/pipermail/odb-announcements/2013/000037.html

ODB is written in portable C++ (both C++98/03 and C++11 are supported) and
you should be able to use it with any modern C++ compiler. In particular, we
have tested this release on GNU/Linux (x86/x86-64/ARM), Windows (x86/x86-64),
Mac OS X (x86), and Solaris (x86/x86-64/SPARC) with GNU g++ 4.2.x-4.8.x,
MS Visual C++ 2005, 2008, 2010, and 2012, Sun Studio 12u2, and Clang 3.x.

The currently supported database systems are MySQL, SQLite, PostgreSQL,
Oracle, and SQL Server. ODB also provides optional profiles for Boost and
Qt, which allow you to seamlessly use value types, containers, and smart
pointers from these libraries in your persistent classes.

More information, documentation, source code, and pre-compiled binaries are
available from:

http://www.codesynthesis.com/products/odb/

Enjoy,
Boris





==============================================================================
TOPIC: Inject std namespace into main()
http://groups.google.com/group/comp.lang.c++/t/5a1fbdc0a014b400?hl=en
==============================================================================

== 1 of 3 ==
Date: Wed, Oct 30 2013 7:48 am
From: SG


On Wednesday, October 30, 2013 12:27:49 AM UTC+1, Alf P. Steinbach wrote:
>
> This is a main difference between a using DIRECTIVE (which you employed)
> and a using DECLARATION (above). The directive only directs lookup. The
> declaration acts more like a declaration. :-)

As for how this "direction" works: It's like the names are injected
into the closest namespace level that contains both, the context in
which you are writing the directive and the namespace you are naming
in the directive. So, for example:

int i;
namespace foo {
namespace bar {
int i;
}
namespace baz {
using namespace bar; // puts the names from ::foo::bar
// "temporarily" into ::foo because
// foo is the "closest" namespace that
// contains both bar and baz.

void func() {i=23;} // i refers to ::foo::bar::i, it is
// found when lookup reaches the foo
// namespace.
}
void another() {i=42;} // i refers to ::i.
}

By "temporarily" I tried to refer to the scope in which the using
directive is "active".

HTH,
SG




== 2 of 3 ==
Date: Wed, Oct 30 2013 7:56 am
From: SG


On Wednesday, September 11, 2013 5:28:23 PM UTC+2, parmenides wrote:
> Hi,
>
> For the flowing code:
>
> #include <iostream>
>
> int cout;
>
> int main()
> {
> using namespace std;
> cout << endl;
> return 0;
> }
>
> I think all symbols in std are injected into main(), that is , the cout is a
> object local to the main(). It should shield the other cout in the global
> namespace. But, the complier has told me:
>
> reference to 'cout' is ambiguous

Right. std::cout and std::endl are found when lookup reaches the
global namespace (::). But since there is already your int-variable
with the same name (cout), you have the ambiguity.

The names are NOT pulled into ::main. That's not how a using directive
works. (see my previous post)

If you want cout to be found when lookup checks the function-local
scope, you need a using _declaration_ for that.




== 3 of 3 ==
Date: Wed, Oct 30 2013 8:05 am
From: SG


On Wednesday, October 30, 2013 3:56:27 PM UTC+1, SG wrote:
>
> Right. std::cout and std::endl are found when lookup reaches the
> global namespace (::). But since there is already your int-variable
> with the same name (cout), you have the ambiguity.
>
> The names are NOT pulled into ::main. That's not how a using directive
> works. (see my previous post)
>
> If you want cout to be found when lookup checks the function-local
> scope, you need a using _declaration_ for that.

Keep in mind that names are searched starting from local scopes and
going to the more global scopes. If/When one or more names are found
in the scope that namelookup is currently focussing on, this kind of
search stops and this is why names from inner scopes can "hide" names
from outer scopes.

In case the names found so far (if any) during unqualified lookup
refer to class members, namelookup will stop. Otherwise, "associated"
namespaces will be checked too (ADL, argument dependent lookup).

I think that covers all the nuts and bolts of unqualified name lookup.

HTH,
SG





==============================================================================
TOPIC: Why string's c_str()? [Overloading const char *()]
http://groups.google.com/group/comp.lang.c++/t/e6c9d55b4c332550?hl=en
==============================================================================

== 1 of 9 ==
Date: Wed, Oct 30 2013 12:00 pm
From: DSF


Hello group!

I have been using/writing my own string class for some time now. A
while back, I discovered the wonderful ability to overload const char
*. I was now able to use my string anywhere I could use const char *.
But... I had always wondered why the STL string class uses c_str()
instead of overloading const char *(). My first thought on the
subject is that it frees the string class to store the string in any
manner the coder chooses. One option would be to use the format of
[length of string][string]. But then I started reading articles
online stating that overloading const char *() is a bad idea because
it can allow unintended implicit conversions. Of course, most of
these articles used the typical overkill terms such as "dangerous" and
"evil", etc. Without going into detail of the specific dangers and
evils.

I came upon a discussion at the site below that intrigued me.

http://www.dreamincode.net/forums/topic/260662-operator-const-char-and-operator-caveats-with-overloads/

Since the site thread is fairly old, I decided to ask here.

I've reposted a small section here. (I hope they don't mind.)

//start
D.I.C Lover
Re: operator const char* and operator[] - caveats with overloads?

Posted 21 December 2011 - 02:18 PM
The problems will arise from ambiguous conversions. In C++, if you
have a statement with two different types, the compiler will try to
find a cast for one or the other so that the statement can be
evaluated. Now when you start adding conversions like this, you can't
prepare for every possible use of your class. Because of this, someone
who doesn't fully understand the language might try to use your class
in such a way that ambiguous conversions occur. The fact that the
designers of the std::string class left out a conversion operator, is
enough of an explanation to tell me that it should be avoided.

View Postmonkey_05_06, on 21 December 2011 - 03:52 PM, said:
What would be considered "accidental" or "unintended" conversions to
char*?

Things that come to mind are.

01 String a, b;
02 if (a==B) {}
03 if (a=="str") {}
04 if ("str"==a) {}
05 if ("str"!=a) {}
06 if (a > B) {}
07 if (a <= B) {}
08 if ("str" < a) {}
09 *a;
10 (a + 5);

All these things will suddenly just compile, but none of these will do
what you expect from a String class.

What Karel-Lodewijk said is exactly what I am talking about. Without a
conversion operator, most of those statements will not compile. With a
conversion operator they WILL compile, but not do what you expected.
If you feel like chasing around hard to find bugs, then leave it in
there, if not just add a function like the std::string::c_str().
//end


The examples above along with "none of these will do what you expect
from a String class" aroused my curiosity. Except for 09 and 10, I
was pretty certain the rest would do what I expect them to.

So I compiled the above with my string class, adding the harmless
getch() (wait for a keypress) within all of the {} so the whole thing
wouldn't be optimized away and to test the result of the if
statements. I also ran it with string 'a' initialized to "str".

Every single one of the first 8 did exactly what I expected.

9 did nothing (of course), but walking through the assembly code
confirmed it returned a pointer to the first character of string 'a'.
I added a char c; statement, then c = *a; then a printf using 'c' and
it worked. Funny, the compiler won't optimize *a; away, but with the
statement c=*a; it will optimize away the c= if you don't use the 'c'
leaving the *a code intact.

10 I wasn't sure about. Of course, it also did nothing on the
surface, but below it got a pointer to 'a', added 5 to it and returned
the resulting pointer. An overrun with a = "" or a = "str", but
that's not the point.

So what is the "danger" of overloading * (or in the case of above *
and [])? Everything I've written so far has worked as I expected, and
it's very convenient and looks more elegant than the alternatives when
one needs to pass a const char * to an API call, etc.

"'Later' is the beginning of what's not to be."
D.S. Fiscus




== 2 of 9 ==
Date: Wed, Oct 30 2013 1:34 pm
From: Paavo Helde


DSF <notavalid@address.here> wrote in
news:iqh279hter1j3kvtmqr19o1g5ggkvdrokj@4ax.com:
> But then I started reading articles
> online stating that overloading const char *() is a bad idea because
> it can allow unintended implicit conversions. Of course, most of
> these articles used the typical overkill terms such as "dangerous" and
> "evil", etc. Without going into detail of the specific dangers and
> evils.

Nitpicking: it is called 'operator const char*', not just 'const char*'.

One failing scenario (there are others no doubt): say you have a class
storing a const char* pointer for a later use, assuming it is a static or
otherwise living-forever pointer:

class A {
public:
void f(const char* s) {s_=s;}
void g() {std::cout << s_;}
private:
const char* s_;
};

Now this is set by e.g.

A x;
void h(const char* s) {
x.f(s);
}

int main() {
h("foo");
x.g();
}

Now let's say somebody comes along and cleans up some code to use your
string class instead of const char* in h():

void h(const MyString& s) {
x.f(s);
}

int main() {
h("foo");
x.g(); // BOOM!
}

Everything compiles fine and may even run sometimes as expected, but
nevertheless the pointer which is stored is temporary and turns invalid
immediately after h() returns. Some innocent-looking code cleanup has
just created a dormant bug.

Now imagine this is a million-line system, functions are hundreds of
lines long, half of the code from 20 years back, class A and function h
managed by different teams, etc., and you should start to see why such
automatic conversions are evil. If there is a compile error when calling
x.f(), then somebody has to check the code and at least has a chance to
notice that a temporary pointer must not be passed to class A as it wants
to store it.

Yes, in case of perfect worlds and omnipotent programmers such automatic
conversions are fine. However, in that case C++ is not needed at all,
omnipotent programmers can write machine code directly ;-)

Cheers
Paavo




== 3 of 9 ==
Date: Wed, Oct 30 2013 5:38 pm
From: Öö Tiib


On Wednesday, 30 October 2013 21:00:26 UTC+2, DSF wrote:
> But... I had always wondered why the STL string class uses c_str()
> instead of overloading const char *().

Most of novices to C or C++ are confused by tendency of raw arrays to
transform into raw pointers on most cases of usage. So standard library
designers decided not to mimic that confusing behavior.

Generally all implicit conversions are evil and raw pointers are rarely
needed in modern C++. So why you care?




== 4 of 9 ==
Date: Wed, Oct 30 2013 8:45 pm
From: "Alf P. Steinbach"


On 30.10.2013 21:34, Paavo Helde wrote:
>
> Now let's say somebody comes along and cleans up some code to use your
> string class instead of const char* in h():
>
> void h(const MyString& s) {
> x.f(s);
> }
>
> int main() {
> h("foo");
> x.g(); // BOOM!
> }
>
> Everything compiles fine and may even run sometimes as expected, but
> nevertheless the pointer which is stored is temporary and turns invalid
> immediately after h() returns. Some innocent-looking code cleanup has
> just created a dormant bug.

Well that doesn't happen with MY string class. And so, lacking
information about the OP's string class, it does not necessarily happen
with that class either (although I suspect it would). In short, while
the failure mode idea is in the right direction, you're making some
assumptions here that do not necessarily hold, leading to an invalid
conclusion about inherent danger of implicit conversion.

In other words, a little fallacy. ;-)

Equally important for discussing goodness and badness of something like
this conversion, one must consider advantages and problems. The above
scenario, when it happens, shows that implicit conversion can expose
problems in bad code. This can be considered an advantage -- on top of
the sheer convenience of the implicit conversion, when done properly.


Cheers & hth.,

- Alf





== 5 of 9 ==
Date: Wed, Oct 30 2013 8:52 pm
From: "Alf P. Steinbach"


On 31.10.2013 01:38, Öö Tiib wrote:
> On Wednesday, 30 October 2013 21:00:26 UTC+2, DSF wrote:
>> But... I had always wondered why the STL string class uses c_str()
>> instead of overloading const char *().
>
> Most of novices to C or C++ are confused by tendency of raw arrays to
> transform into raw pointers on most cases of usage. So standard library
> designers decided not to mimic that confusing behavior.
>
> Generally all implicit conversions are evil and raw pointers are rarely
> needed in modern C++. So why you care?
>

I think, for high level programming one would be better off using a more
purely high level language.

C++, while supporting abstraction, deals with more low level stuff such
as calling OS API functions, and doing that very efficiently.

I find it very annoying both to write and to read all those .c_str()
explicit conversion operations. It would be okay if it was a rarely
invoked operation, full of dangers. But it's commonplace and harmless
(well mostly, but then anything /can/ be dangerous in C++, and one can't
avoid using integers or whatever).


Cheers & hth.,

- Alf





== 6 of 9 ==
Date: Wed, Oct 30 2013 11:47 pm
From: Tobias Müller


DSF <notavalid@address.here> wrote:

[...]

> I've reposted a small section here. (I hope they don't mind.)
>
> //start

[...]

> 01 String a, b;
> 02 if (a==B) {}
> 03 if (a=="str") {}
> 04 if ("str"==a) {}
> 05 if ("str"!=a) {}
> 06 if (a > B) {}
> 07 if (a <= B) {}
> 08 if ("str" < a) {}
> 09 *a;
> 10 (a + 5);
>
> All these things will suddenly just compile, but none of these will do
> what you expect from a String class.

[...]

> The examples above along with "none of these will do what you expect
> from a String class" aroused my curiosity. Except for 09 and 10, I
> was pretty certain the rest would do what I expect them to.
>
> So I compiled the above with my string class, adding the harmless
> getch() (wait for a keypress) within all of the {} so the whole thing
> wouldn't be optimized away and to test the result of the if
> statements. I also ran it with string 'a' initialized to "str".
>
> Every single one of the first 8 did exactly what I expected.

If your class defines all those operators, everything should be fine. And
IMO a string class _without_ those operators is incomplete.
But in the case it doesn't, all those operators will work on raw pointers.

So in fact those examples are a bit unfortunate, because most of the
expressions are usually considered valid and meaningful for strings.

[...]

> So what is the "danger" of overloading * (or in the case of above *
> and [])? Everything I've written so far has worked as I expected, and
> it's very convenient and looks more elegant than the alternatives when
> one needs to pass a const char * to an API call, etc.

The real dangers lie in expressions that are usually not considered valid
for strings or that are controversial.

Most dangerous is IMO the implicit conversion from const char* to bool:
MyString a;
if (a) // always true
{...}

This one is easy to spot, but it could also be a more complex boolean
expression with a subtle error.

Tobi




== 7 of 9 ==
Date: Thurs, Oct 31 2013 10:26 am
From: Öö Tiib


On Thursday, 31 October 2013 05:52:28 UTC+2, Alf P. Steinbach wrote:
> On 31.10.2013 01:38, Öö Tiib wrote:
> > On Wednesday, 30 October 2013 21:00:26 UTC+2, DSF wrote:
> >> But... I had always wondered why the STL string class uses c_str()
> >> instead of overloading const char *().
> >
> > Most of novices to C or C++ are confused by tendency of raw arrays to
> > transform into raw pointers on most cases of usage. So standard library
> > designers decided not to mimic that confusing behavior.
> >
> > Generally all implicit conversions are evil and raw pointers are rarely
> > needed in modern C++. So why you care?
>
> I think, for high level programming one would be better off using a more
> purely high level language.

It is difficult to find any higher and better scalable general purpose language
(IOW no limits) than C++. High level solutions should be indeed made with
problem-oriented stuff (like SAP Business Objects) if your problem domain
has such thing and the problem is within limits of it.

> C++, while supporting abstraction, deals with more low level stuff such
> as calling OS API functions, and doing that very efficiently.

Lets say Windows API CreateFileW. It has 7 parameters and at least 10
different responsibilities. If we call such monsters raw and unenwrapped
then the conversions are least of our problems I suppose.
So we write a particular OS API call only once in wrapper and compiler
optimises the wrapper call mostly away anyway.

> I find it very annoying both to write and to read all those .c_str()
> explicit conversion operations. It would be okay if it was a rarely
> invoked operation, full of dangers. But it's commonplace and harmless
> (well mostly, but then anything /can/ be dangerous in C++, and one can't
> avoid using integers or whatever).

I see that c_str() used rather rarely. Basically only in interfaces with
alien languages. Say converting to or wrapping C interface. Interfaces are
rarely maintained. Where else you see masses of that c_str() used?




== 8 of 9 ==
Date: Thurs, Oct 31 2013 11:03 am
From: "Alf P. Steinbach"


On 31.10.2013 18:26, Öö Tiib wrote:
> On Thursday, 31 October 2013 05:52:28 UTC+2, Alf P. Steinbach wrote:
>> On 31.10.2013 01:38, Öö Tiib wrote:
>>> On Wednesday, 30 October 2013 21:00:26 UTC+2, DSF wrote:
>>>> But... I had always wondered why the STL string class uses c_str()
>>>> instead of overloading const char *().
>>>
>>> Most of novices to C or C++ are confused by tendency of raw arrays to
>>> transform into raw pointers on most cases of usage. So standard library
>>> designers decided not to mimic that confusing behavior.
>>>
>>> Generally all implicit conversions are evil and raw pointers are rarely
>>> needed in modern C++. So why you care?
>>
>> I think, for high level programming one would be better off using a more
>> purely high level language.
>
> It is difficult to find any higher and better scalable general purpose language
> (IOW no limits) than C++.

For the "better" you would have to define what you mean by that.

But re higher level general purpose languages, C# and Java come to mind.
These languages have module support, currently lacking in C++ (I don't
know the status of Daveed's proposal). I think these languages scale
rather well, probably better than C++ currently does, due to the lack of
module support in C++.

Even higher level than that you have Python, which works nicely with
C++, but doesn't really scale (as was discovered with YouTube, IIRC).


> High level solutions should be indeed made with
> problem-oriented stuff (like SAP Business Objects) if your problem domain
> has such thing and the problem is within limits of it.
>
>> C++, while supporting abstraction, deals with more low level stuff such
>> as calling OS API functions, and doing that very efficiently.
>
> Lets say Windows API CreateFileW. It has 7 parameters and at least 10
> different responsibilities. If we call such monsters raw and unenwrapped
> then the conversions are least of our problems I suppose.
> So we write a particular OS API call only once in wrapper and compiler
> optimises the wrapper call mostly away anyway.

One cannot wrap all Windows API functions.

And it gets worse when you add in further 3rd party libraries, such as
OpenCV.

Not to mention the C++ standard library itself... ;-)


>> I find it very annoying both to write and to read all those .c_str()
>> explicit conversion operations. It would be okay if it was a rarely
>> invoked operation, full of dangers. But it's commonplace and harmless
>> (well mostly, but then anything /can/ be dangerous in C++, and one can't
>> avoid using integers or whatever).
>
> I see that c_str() used rather rarely. Basically only in interfaces with
> alien languages. Say converting to or wrapping C interface. Interfaces are
> rarely maintained. Where else you see masses of that c_str() used?

In C++03 even std::ofstream constructors required raw C string pointers
for the filenames.

In other words, library functions taking raw C string pointers is a
widespread practice, so "natural" that the std::ofstream design without
std::string argument constructor was adopted.

Regarding the rationale for that, it removes a header dependency and it
generally does not add any conversion, since the conversion generally
has to be done at some level anyway, but I suspect that often it's done
simply because programmers have become used to interfaces like that.


Cheers & hth.,

- Alf





== 9 of 9 ==
Date: Fri, Nov 1 2013 8:53 am
From: Öö Tiib


On Thursday, 31 October 2013 20:03:12 UTC+2, Alf P. Steinbach wrote:
> On 31.10.2013 18:26, Öö Tiib wrote:
> > On Thursday, 31 October 2013 05:52:28 UTC+2, Alf P. Steinbach wrote:
> >> On 31.10.2013 01:38, Öö Tiib wrote:
> >>> On Wednesday, 30 October 2013 21:00:26 UTC+2, DSF wrote:
> >>>> But... I had always wondered why the STL string class uses c_str()
> >>>> instead of overloading const char *().
> >>>
> >>> Most of novices to C or C++ are confused by tendency of raw arrays to
> >>> transform into raw pointers on most cases of usage. So standard library
> >>> designers decided not to mimic that confusing behavior.
> >>>
> >>> Generally all implicit conversions are evil and raw pointers are rarely
> >>> needed in modern C++. So why you care?
> >>
> >> I think, for high level programming one would be better off using a more
> >> purely high level language.
> >
> > It is difficult to find any higher and better scalable general purpose language
> > (IOW no limits) than C++.
>
> For the "better" you would have to define what you mean by that.

"Better scalable" in sense that C++ is better doing multithreading and
multiprocessing and multi-computing and so on. While language does not contain
anything supporting it the processes start, fork and shut down faster in practice.

> But re higher level general purpose languages, C# and Java come to mind.
> These languages have module support, currently lacking in C++ (I don't
> know the status of Daveed's proposal). I think these languages scale
> rather well, probably better than C++ currently does, due to the lack of
> module support in C++.

That is true defect of our legal system (IOW standard C++). In actual reality
we have all the dlls, libraries and executables like everybody. Ours work
even better than modules of others in practice. Every "oh so high" language
there uses C or C++ modules. It is pity that our standard avoids legalising
that reality. It however can't be used as argument since if everybody use
our modules and processes how come we don't have them? ;-)

> Even higher level than that you have Python, which works nicely with
> C++, but doesn't really scale (as was discovered with YouTube, IIRC).

We always have used such sidekick script languages in real projects. Python
integrates simpler than Lisp and is better readable than Perl. Something that
does not scale up can not be considered "higher" but more like "servant". ;-)

> > High level solutions should be indeed made with
> > problem-oriented stuff (like SAP Business Objects) if your problem domain
> > has such thing and the problem is within limits of it.
> >
> >> C++, while supporting abstraction, deals with more low level stuff such
> >> as calling OS API functions, and doing that very efficiently.
> >
> > Lets say Windows API CreateFileW. It has 7 parameters and at least 10
> > different responsibilities. If we call such monsters raw and unenwrapped
> > then the conversions are least of our problems I suppose.
> > So we write a particular OS API call only once in wrapper and compiler
> > optimises the wrapper call mostly away anyway.
>
> One cannot wrap all Windows API functions.

One does not /have/ to. In practice it is often advisable not to. For majority of
common things one has option to take a library that already does it
(like boost.program_options, boost::filesystem, boost::asio or boost::interprocess).
If one needs lot of things then there are whole frameworks too (like Qt). So what
remains are very few "special" calls that the libraries do not wrap but that the
requirements demand.

> And it gets worse when you add in further 3rd party libraries, such as
> OpenCV.

I have regretfully had no time to mess with OpenCV but my impression was that it
has C++ API and C 'char*' API of it is deprecated?

> Not to mention the C++ standard library itself... ;-)

There are, yes, plenty of things in standard library that are best for nothing.
Decades long legacy results with stuff like that. Just recently I discovered
(someone asked in comp.lang.c++.moderated) that some things even are
described by standard to possibly do nothing whatsoever like:

std::cin.rdbuf()->pubsetbuf(buffer, sizeof(buffer));

> >> I find it very annoying both to write and to read all those .c_str()
> >> explicit conversion operations. It would be okay if it was a rarely
> >> invoked operation, full of dangers. But it's commonplace and harmless
>
> >> (well mostly, but then anything /can/ be dangerous in C++, and one can't
> >> avoid using integers or whatever).
> >
> > I see that c_str() used rather rarely. Basically only in interfaces with
> > alien languages. Say converting to or wrapping C interface. Interfaces are
> > rarely maintained. Where else you see masses of that c_str() used?
>
> In C++03 even std::ofstream constructors required raw C string pointers
> for the filenames.

Since contents of those raw byte buffers passed to fstream constructors as
"file name" are anyway platform specific we typically need something
(like boost::filesystem) to handle that case in sane manner anyway.

> In other words, library functions taking raw C string pointers is a
> widespread practice, so "natural" that the std::ofstream design without
> std::string argument constructor was adopted.
>
> Regarding the rationale for that, it removes a header dependency and it
> generally does not add any conversion, since the conversion generally
> has to be done at some level anyway, but I suspect that often it's done
> simply because programmers have become used to interfaces like that.

I think I/O library is bad example anyway. Bjarne wrote it ages ago; 2 to 4
other guys "repaired" it and now it is what it is. It gets things done but
nothing of it is pretty. In reality we have abstracted it (or some other I/O)
far away under things like "database", "client", "configuration" etc.





==============================================================================
TOPIC: String and interfacing with functions using char*
http://groups.google.com/group/comp.lang.c++/t/a7d848d28878a317?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Oct 30 2013 12:58 pm
From: DSF


On Wed, 30 Oct 2013 03:02:10 -0700 (PDT), guinness.tony@gmail.com
wrote:

>On Wednesday, 30 October 2013 02:37:08 UTC, DSF wrote:
>> >
>> >> &s[0] works with STL string, but produces the error "Must take address
>> >> of a memory location."
>> >
>> >Presumably this is a typo, where the intended meaning was
>> >
>> ><< &s[0] works with STL string, but with the String class it produces
>> >the error "Must take address of a memory location.">
This was a mistake, I should have said with my string class.

>> I just tried changing:
>> char operator [] (int index) const {return str[index];}
>> to
>> char& operator [] (int index) const {return str[index];}
>>
>> and it works. It still functions like above, but can also be used as
>> a pointer, as in &str[0].
>
>No no NO! DON'T do this.
>
>The member function explicitly operates only on const objects.
>NEVER hand out mutable references from const member functions.
>Separate the functionality between const and non-const members:
>
>char& operator[](size_t const index) { return str[index]; }
>char operator[](size_t const index) const { return str[index]; }
>
>(the latter could, like std::string, return a char const&).

I changed the header file for my string class to the above.

...which leads me right back to the same problem I started with when
using &s[0]. Error: "Must take address of a memory location."

Ignore the above two paragraphs. There used to be six. I left them
in to illustrate my stupidity! I spent half an hour trying to get rid
of that error. I changed back to my original code that worked and
still got the error! That's when it hit me. I have two versions of
the string class, one for ANSI and one for wide. I've adopted
Window's style of post fixing them with A or W. I had recently
converted the project to unicode. I was changing the A version, but
the compiler was using the W version.

Just thinking aloud:
The code works fine, but I'd really prefer that the internal string
be read only to the outside world except for initialization or
assignment. But I have to weigh that against having to create a
temporary char array every time I use a function or API call that
returns a string in the form of a pointer in the parameter list. I
think I'll live with the internal string being mutable and save all of
the extra work!

And why the const in "size_t const index"? index is going to be
passed by value. Or am I missing something?

Thank you.

"'Later' is the beginning of what's not to be."
D.S. Fiscus




== 2 of 2 ==
Date: Wed, Oct 30 2013 1:52 pm
From: Chris Vine


On Tue, 29 Oct 2013 23:04:22 -0400
DSF <notavalid@address.here> wrote:
> I did that in 198X. I'd written a symbolic 6502 (Commodore, not
> Apple) assembler, assembling it with an assembler I'd typed in from a
> magazine. (Ahhh! There's nothing like that day when your assembler
> first assembles itself!) I didn't care for the few available text
> editors, so I wrote my own. Had them both stored on an EEPROM and
> could start either with BASIC's SYS command. I can't say I remember
> how the cursor functioned in the editor, though.
>
> Started assembly with a simple ML monitor (VICMON). Now those were
> the *FUN* days! Backward branches could just be filled in, but forward
> ones I usually set to branch to themselves. That way, if I forgot to
> go back and change the target once I knew what it was, the program
> would go into an infinite loop. Then I could just break out of the
> loop with the IP at the loop point. You could only branch -128 to 127
> bytes from the instruction, so if you weren't sure about a branch, you
> could always stick in a few NOPs so you could use the opposite branch
> condition to branch over a JMP to the farther location. Speaking of
> JMPs, if you had to insert some code to fix a bug, etc. most of the
> branches would adjust automatically, being relative. But JMPs and
> references to absolute memory addresses had to be found and fixed by
> hand. No code/data separation back then, if the data buffer wasn't
> going to grow beyond the buffer's size or was static, you put it
> adjacent to its code. No asking for memory, either. If it was there,
> it was yours to do with as you pleased, (outside of kernel memory
> areas, of course.)
>
> The good old days!

The Commodore 64 range and derivatives (I think that is what you had in
mind), and possibly also the preceding VIC, had a 6510 processor, but
with the same instruction set as the 6502. It was a lovely thing to
program in machine code/assembler. It had a well supported assembler
and monitor and documentation, and best of all an addressable back slot
to which you could attach peripherals. I used it amongst other things
to generate morse code which, via a mechanical relay, keyed a RF
transmitter, but you could do practically anything with it. A kind of
Raspberry Pi for the 80s.

And, as you say, because it was an open book with no distinction
between code and data memory, you could do yucky things like implement
polymorphism by directly poking at the memory.

Chris







==============================================================================
TOPIC: Compiler for Linux
http://groups.google.com/group/comp.lang.c++/t/c1bd2a41213c7ef1?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Oct 30 2013 4:48 pm
From: "Paul ( The Troll )"


On Wednesday, 30 October 2013 11:41:01 UTC, Victor Bazarov wrote:
> On 10/29/2013 8:17 PM, Paul ( The Troll ) wrote:
>
> > On Tuesday, 29 October 2013 20:24:00 UTC, Paul ( The Troll ) wrote:
>
> >> [...]
>
> >> Oh right I see that QT Creator uses gcc. I may give Eclipse a try too. TY
>
> >
>
> > Had to play around a bit to get Eclipse setup but it's ok now.
>
>
>
> And I uninstalled Firefox that our IT pushes on us every Wednesday. As
>
> usual, it's OK again. SX

FF is the only browser I have on Linux so far, I am downloading Chrome now too.





==============================================================================
TOPIC: C and C++
http://groups.google.com/group/comp.lang.c++/t/0c5cd0246395d2ed?hl=en
==============================================================================

== 1 of 10 ==
Date: Thurs, Oct 31 2013 4:09 pm
From: "Bill Cunningham"


Ok what is it that's so much easier in C++ than C? It's been so long
since I've looked at C++ I can't remember much about it. Instead of free()
you can use delete if I remember right. You need a whole extra header
fstream in order to save to files. Is it worth the overhead in the binaries?
iostream is a big library.

Bill






== 2 of 10 ==
Date: Thurs, Oct 31 2013 4:59 pm
From: Victor Bazarov


On 10/31/2013 8:09 PM, Bill Cunningham wrote:
> Ok what is it that's so much easier in C++ than C? It's been so long
> since I've looked at C++ I can't remember much about it. Instead of free()
> you can use delete if I remember right. You need a whole extra header
> fstream in order to save to files. Is it worth the overhead in the binaries?
> iostream is a big library.

Pick up a decent C++ book and give it a good read. And stop trolling.

V
--
I do not respond to top-posted replies, please don't ask




== 3 of 10 ==
Date: Thurs, Oct 31 2013 8:59 pm
From: Barry Schwarz


On Thu, 31 Oct 2013 19:09:13 -0500, "Bill Cunningham"
<nospam@nspam.invalid> wrote:

> Ok what is it that's so much easier in C++ than C? It's been so long

Given the problems you have demonstrated with C, it is unlikely that
C++ holds any advantage for you.

>since I've looked at C++ I can't remember much about it. Instead of free()
>you can use delete if I remember right. You need a whole extra header

You remember wrong.

>fstream in order to save to files. Is it worth the overhead in the binaries?

Wrong again. Besides, headers don't result in any object code so why
is including one more a big deal?

>iostream is a big library.

It doesn't matter how big the library is. The linker will bring in
only the functions required for your program

--
Remove del for email




== 4 of 10 ==
Date: Thurs, Oct 31 2013 9:03 pm
From: "Alf P. Steinbach"


On 01.11.2013 01:09, Bill Cunningham wrote:
> Ok what is it that's so much easier in C++ than C? It's been so long
> since I've looked at C++ I can't remember much about it.

Recall that C++ was originally "C with classes".

So that's the basic thing that originally was added to C to create C++.
Essentially it's about having /language support/, with strict type
checking, of what you have to do manually in C. For example:

* C++ supports derived classes. In C you have to cast to/from a
conceptual "base class member" placed first in the struct.

* C++ supports the o.m() notation for member functions. In C you have to
write m( &o ), and (modulo some "generics" support introduced in C11)
you have to invent different names for m overloads.

* C++ supports virtual member functions in a type safe way. Doing this
manually in C is a nightmare, even with supporting macros, and involves
a lot of very unsafe casting. Essentially, C++ has a /type safe implicit
downcast/, but you don't see it until you try to do the same in C, at
which point most programmers choose to trade away some efficiency in
order to simplify the programming, which IMHO trades away the whole
point of using C in the first place.

I suspect the third point was why Bjarne found it worthwhile to create a
language extension, which turned into a whole new language with support
for far more than that. Including, as you did recall, more easily
customizable allocation machinery. Which is in support of the strong
typing, namely an all-or-nothing guarantee for allocation +
initialization, sort of like a database transaction but transparently.

However, the all-or-nothing guarantee for allocation + initialization
requires exceptions and so it wasn't added until around 1990 somewhere
(1989? I can't recall).

In short, at the start it was virtual member functions, with that
ordinarily-not-very-apparent implicit type safe downcasting.


> Instead of free() you can use delete if I remember right.

There's a customizable more type safe memory allocation machinery, yes.

And this machinery ties in with the all-or-nothing guarantee for
allocation + initialization.

And that guarantee ties in with and requires exceptions.

Exceptions are another thing that that you really don't want to do
manually in C. But then the difficulty of doing it in C means that most
"pure C" programmers are unfamiliar with it and therefore utterly fail
to see the utility. Like, why on Earth would we want that complication?

Well, they /simplify/ things directly, when you have language support,
and they make possible the allocation + initialization all-or-nothing
guarantee, which is of immense practical value. They do have a steep
cost, though, namely that the supporting internal machinery must be
dynamically initialized, which can be difficult to arrange in e.g.
driver software. Also, difficult for embedded programming.

As I recall Bjarne postponed adding exceptions until Andrew Koenig and
he arrived at some satisfactory ideas about it. At that time exception
handling had been added in a number of languages (notably Ada, but
academics will no doubt prefer to mention e.g. Common Lisp), so it did
not require genius to see its utility, merely familiarity with the
programming world outside the C sphere. E.g. I remember writing an
enthusiastic article about Ada exception handling in the middle 80s. But
I think it did require folks like Bjarne and Andrew in order to see how
to integrate that concept with C, and how it could offer new and very
useful guarantees, thereby greatly simplifying the programming.


> You need a whole extra header
> fstream in order to save to files. Is it worth the overhead in the binaries?
> iostream is a big library.

It depends.

For small toy programs, yes, why not.

One notch up in size you (or I) start considering alternatives.

Even more up in size, hey, that added size overhead is now insignificant.

But the main reason that I'd like to avoid iostreams as much as possible
is that they generally cause needlessly verbose, complex and brittle
client code, with usually pretty inefficient i/o, all in order to get a
little type safety that by no means is very complete. It sort of reminds
me of Benjamin Franklin. Readers can probably guess why.


Cheers & hth.,

- Alf





== 5 of 10 ==
Date: Thurs, Oct 31 2013 10:10 pm
From: "Alf P. Steinbach"


On 01.11.2013 04:59, Barry Schwarz wrote:
> On Thu, 31 Oct 2013 19:09:13 -0500, "Bill Cunningham"
> <nospam@nspam.invalid> wrote:
>
>> Ok what is it that's so much easier in C++ than C? It's been so long
>
> Given the problems you have demonstrated with C, it is unlikely that
> C++ holds any advantage for you.

Regardless of the merit or lack thereof of the above evaluation of the
OP, very few clc++ readers will benefit from that statement.

The statement is also quite offensive.

I know, we're not yet at the point again where out-of-the-blue
needlessly offensive statements are not ordinary in clc++, and perhaps
we'll never get there again, but it's a good ideal to aim for.


>> since I've looked at C++ I can't remember much about it. Instead of free()
>> you can use delete if I remember right. You need a whole extra header
>
> You remember wrong.

That depends on the interpretation. I see your interpretation (replace
free() with delete and don't correspondingly replace malloc with new) as
adversarial. I would say that Bill does remember correctly -- then
choosing a more natural interpretation where the statement makes sense.


>> fstream in order to save to files. Is it worth the overhead in the binaries?
>
> Wrong again.

I'm sorry, but that statement does not make sense to me.


> Besides, headers don't result in any object code

Sorry, that's incorrect.

It also misrepresents the OP, who has not claimed anything in that
direction.


> so why is including one more a big deal?

Including headers add to build time.


>> iostream is a big library.
>
> It doesn't matter how big the library is.

Oh, it does. In particular for its complexity, which affects both the
effort needed to learn how to use it, and the effort needed to test and
correct client code. In other words, there's a fairly direct connection
between library size and financial cost (in man-hours) of using it.


> The linker will bring in
> only the functions required for your program

If one is lucky.

iostreams, which the OP is discussing, is well known for adding a fair
amount of baggage.


- Alf





== 6 of 10 ==
Date: Fri, Nov 1 2013 12:24 am
From: Ian Collins


Alf P. Steinbach wrote:
> On 01.11.2013 04:59, Barry Schwarz wrote:
>> On Thu, 31 Oct 2013 19:09:13 -0500, "Bill Cunningham"
>> <nospam@nspam.invalid> wrote:
>>
>>> Ok what is it that's so much easier in C++ than C? It's been so long
>>
>> Given the problems you have demonstrated with C, it is unlikely that
>> C++ holds any advantage for you.
>
> Regardless of the merit or lack thereof of the above evaluation of the
> OP, very few clc++ readers will benefit from that statement.
>
> The statement is also quite offensive.

"Bill" is well known on c.l.c, renowned for asking almost the same
question many times over many years. Anyone familiar with that group
would agree with Barry.

--
Ian Collins




== 7 of 10 ==
Date: Fri, Nov 1 2013 5:48 am
From: Stuart


On 01.11.2013 04:59, Barry Schwarz wrote:
[snip]
>> Given the problems you have demonstrated with C, it is unlikely that
>> C++ holds any advantage for you.

On 13/11/01, Alf P. Steinbach wrote:
> Regardless of the merit or lack thereof of the above evaluation of the
> OP, very few clc++ readers will benefit from that statement.

Probably true. If Barry had written "The problems you have shown to us
in previous posts indicate that C++ is in fact not better suited for
your specific problem space than C.", it would have been much more
clearer to the "average" clc++ reader.

> The statement is also quite offensive.

Also probably true, but IMHO your statement can also be considered
offensive. My formulation would have been "I think that your statement
is offensive".

> I know, we're not yet at the point again where out-of-the-blue
> needlessly offensive statements are not ordinary in clc++, and
> perhaps we'll never get there again, but it's a good ideal to aim
> for.

+1.

Regards,
Stuart





== 8 of 10 ==
Date: Fri, Nov 1 2013 6:41 am
From: Juha Nieminen


Bill Cunningham <nospam@nspam.invalid> wrote:
> Ok what is it that's so much easier in C++ than C?

http://warp.povusers.org/programming/cplusplus_superior_to_c.html

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---




== 9 of 10 ==
Date: Fri, Nov 1 2013 8:51 am
From: "Paul ( The Troll )"


On Thursday, 31 October 2013 23:09:13 UTC, Bill Cunningham wrote:
> Ok what is it that's so much easier in C++ than C?

C++ References are very good.

>It's been so long
>
> since I've looked at C++ I can't remember much about it. Instead of free()
>
> you can use delete if I remember right. You need a whole extra header
>
> fstream in order to save to files. Is it worth the overhead in the binaries?
>
> iostream is a big library.
>
>
>
The IO lib you use,if any, will depend on your target platform. You may just call the system IO routines directly. Bear in mind you can always call printf in C++ if you choose to.




== 10 of 10 ==
Date: Fri, Nov 1 2013 9:09 am
From: woodbrian77@gmail.com


On Friday, November 1, 2013 12:10:42 AM UTC-5, Alf P. Steinbach wrote:
> On 01.11.2013 04:59, Barry Schwarz wrote:
>
>
> > The linker will bring in
> > only the functions required for your program
>
> If one is lucky.
>
>

I think Mr. Kanze and others have talked about giving functions
their own source/implementation files in order to minimize the
size of executables. I sometimes split a function off into a
separate file like that.


Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net




==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en

To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

No comments: