Monday, August 29, 2016

Digest for comp.lang.c++@googlegroups.com - 20 updates in 6 topics

ram@zedat.fu-berlin.de (Stefan Ram): Aug 29 12:31PM

>The application: I have a really big collection of Ts stored on a disk,
 
A file does not contain objects.
 
Maybe they were written with
 
#include <stdio.h>
...
fwrite( &object, sizeof object, count, file );
 
. But it is possible that such a file is not readable by
another C++ implementation.
 
Often people use programmer-controlled serialization to
write representations of objects to a file and programmer-
controlled interpreters to read them in from a file, in
which case it is obvious that it is entirely up to the
programmer which type is used to represent the data read.
ram@zedat.fu-berlin.de (Stefan Ram): Aug 29 09:15PM

For my German-language C++ tutorial,
I wanted to use this program as an example:
 
#include <initializer_list>
#include <ostream>
#include <iostream>
 
using namespace ::std::literals;
 
int main()
{ ::std::cout << "echo"s << '\n';
::std::cout << "echo"s << '\n';
{ auto s { "echo"s }; ::std::cout << s << '\n'; }
::std::cout << 99 << '\n'; }
 
I wanted to explain, roughly, this:
 
- There are four ::std::string objects:
The three »"echo"s« objects and the
object called »s«.
 
- The first three ::std::string objects
are temporaries (xvalues), while the
object »s« is not a temporary.
 
But is it correct to say that the »"echo"s«
objects are /three different/ objects?
 
What if they all have the same address?
(Could this be observable?)
 
And where does the standard say that one cannot
take the address of a temporary? I can find:
 
14.3.2 Template non-type arguments [temp.arg.nontype]
 
1 A template-argument for a non-type template-parameter
shall be a converted constant expression (5.20) of
the type of the template-parameter. For a non-type
template-parameter of reference or pointer type, the
value of the constant expression shall not refer to (or for
a pointer type, shall not be the address of):
 
(1.1) - a subobject (1.8),
(1.2) - a temporary object (12.2),
 
So, 14.3.2p1.2 says that the address of a temporary
object cannot be used as a constant expression /for
certain template arguments/. But my compiler says:
 
main.cpp:9:20: error: taking address of temporary [-fpermissive]
{ ::std::cout <<( &"echo"s == &"echo"s )<< '\n'; }
 
as if this was always disallowed.
ram@zedat.fu-berlin.de (Stefan Ram): Aug 29 09:28PM

>The first three ::std::string objects
>are temporaries (xvalues), while the
>object »s« is not a temporary.
 
Ok, a temporary is /not/ always an xvalue, so
delete »xvalue« above please.
 
I also was searching the standard for the place
where the word »temporary« appears in italics
(outside of a comment) and thus is being /defined/
there, but I have not yet found it.
 
Even though I have not found a definition, an
important criterion should be:
 
»Temporary objects are destroyed as the last step
in evaluating the full-expression (1.9) that
(lexically) contains the point where they were created.«.
ram@zedat.fu-berlin.de (Stefan Ram): Aug 29 09:31PM

>But is it correct to say that the »"echo"s«
>objects are /three different/ objects?
 
Ok, I think I see this now: Since they are
temporary, they are being destroyed at the
end of the evaluation of their full expression,
and so these are three different objects, even
if the should have the same place in memory.
ram@zedat.fu-berlin.de (Stefan Ram): Aug 29 11:02PM

>where the word »temporary« appears in italics
>(outside of a comment) and thus is being /defined/
>there, but I have not yet found it.
 
Maybe the list given at the beginning of 12.2
is intended to be the definition:
 
»Temporaries of class type are created in various
contexts: binding a reference to a prvalue (8.5.3),
returning a prvalue (6.6.3), a conversion that creates a
prvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception
(15.1), and in some initializations (8.5).«
 
But, I was not sure which of those cases is »"a"s«, which
seems to be a temporary to me. Maybe it »returning a prvalue«
because »s« in the end is a function.
 
So, then the definition of a temporary would be that it is
any of the cases listed there.
"R.Wieser" <address@not.available>: Aug 29 09:16PM +0200

Hello all,
 
Fair warning: I'm a novice in regard to using C++ (GCC) *and* using linux
(lubuntu to be exact). If this is not the newsgroup to be asking questions
like the below than please advice which newsgroup(s) to use instead.
 
- - - - - -
First problem, C++ related:
 
I need to transfer the address of a structure to a function, and have only
be able to find a hackish solution for it. The problem is that the variable
I've got is actually a pointer, and I have no idea how to dereference it.
 
The variable declaration and initialisation in case:
 
struct hostent *server;
server = gethostbyname(argv[1]);
 
Now I want to transfer the address stored in the "server" variable to a
function. The only way I was able to do that was to refer to the first (and
in this case only) field in that structure:
 
foobar( (unsigned char*) server->h_addr, ... )
 
I read somewhere that I could use (*server) , but trying it ( (unsigned
char*) (*server) ) gave a compile-time error.
 
In short: How do I dereference that "server" variable so the function
receives a pointer to the structure ?
 
- - - - - -
Second problem, Linux related:
 
As someone wo has spend quite some time on Windows I'm rather accustomed
being able to pick a DLL and look inside it to see which functions it
exposes that I can use (yeah, I still have to generate a library from it and
find the function declarations, but thats not the point).
 
I have no idea how to do the same under Linux (and/or how to convert the
found functions (system calls ?) to something I can use in C++ ).
 
To be honest, I have no idea if the above is even feasible for C++ (GCC)
under linux.
 
I did find an example using "nm", but that only showed the contents of the
.o (library) file, and only if the info was not stripped.
 
I also tried that on the full /usr directory, but could not even find
"fprint" (found buf_fprint" and "str_fprint" though).
 
 
And now I'm on a roll asking questions, one thing I did not expect was to
find multiple (sometimes over 10) same-named header files , most often of
different sizes. Whats the idea behind that, and how should I know which
one of those to include ?
 
Regards,
Rudy Wieser
legalize+jeeves@mail.xmission.com (Richard): Aug 29 07:16PM

[Please do not mail me a copy of your followup]
 
"R.Wieser" <address@not.available> spake the secret code
 
>The variable declaration and initialisation in case:
 
>struct hostent *server;
>server = gethostbyname(argv[1]);
 
Here 'server' is a variable holding the address of a 'hostent'
structure. server *is* the address. If you want to pass the address
of the structure to another function, just use the variable 'server'.
 
It sometimes helps if you read the declarations from right to left
out loud:
 
struct hostent *server;
 
"server is a pointer to a hostent structure"
 
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Vir Campestris <vir.campestris@invalid.invalid>: Aug 29 09:04PM +0100

On 29/08/2016 20:16, R.Wieser wrote:
> find the function declarations, but thats not the point).
 
> I have no idea how to do the same under Linux (and/or how to convert the
> found functions (system calls ?) to something I can use in C++ ).
 
As someone who started using Linux not many years ago after many years
of other systems, which included a _lot_ of Windows - I've almost never
had to do that on Windows. If someone wants you to use their library
they'll provide a .h file, and you include that. Then you link against
the library. It's always just worked on Linux... though I suppose I've
mostly been the library supplier, not the app developer.
 
Andy
"Öö Tiib" <ootiib@hot.ee>: Aug 29 01:06PM -0700

On Monday, 29 August 2016 22:17:10 UTC+3, Richard wrote:
> out loud:
 
> struct hostent *server;
 
> "server is a pointer to a hostent structure"
 
Yes, but it seemed that he wanted host addresses as strings from that
hostent structure. Something like:
 
for ( char **it = server->h_addr_list; *it != nullptr; ++it )
{
foobar( *it, ... );
...
}
 
Of course, I may be wrong, it is not clear what programming language
and in what way he used on Windows.
Paavo Helde <myfirstname@osa.pri.ee>: Aug 29 11:27PM +0300

On 29.08.2016 22:16, R.Wieser wrote:
> char*) (*server) ) gave a compile-time error.
 
> In short: How do I dereference that "server" variable so the function
> receives a pointer to the structure ?
 
No C++ here so far, this is all pure C. Anyway, if you have troubles
with basic syntax like this, then I suggest to start with a proper
textbook or tutorial. First you should make up your mind what language
do you want to learn, C or C++, these are two totally different
languages and raw pointers like above hostent* do not actually appear
very often in proper C++ programs.
 
> find the function declarations, but thats not the point).
 
> I have no idea how to do the same under Linux (and/or how to convert the
> found functions (system calls ?) to something I can use in C++ ).
 
This is very counter-productive, it is much easier and safer to use
documentation. But anyway, first google search shows there are things
like objdump and readelf which might be useful for examining so-s.
 
> .o (library) file, and only if the info was not stripped.
 
> I also tried that on the full /usr directory, but could not even find
> "fprint" (found buf_fprint" and "str_fprint" though).
 
Maybe because there is no such thing like fprint? There are printf and
fprintf though, google
 
man fprintf
 
for example.
 
> find multiple (sometimes over 10) same-named header files , most often of
> different sizes. Whats the idea behind that, and how should I know which
> one of those to include ?
 
Documentation? For C++ see e.g.
 
https://isocpp.org/faq
http://en.cppreference.com/w/
http://www.cplusplus.com/
 
HTH
Paavo
jacobnavia <jacob@jacob.remcomp.fr>: Aug 29 11:19PM +0200

Le 29/08/2016 à 21:16, R.Wieser a écrit :
> find multiple (sometimes over 10) same-named header files , most often of
> different sizes. Whats the idea behind that, and how should I know which
> one of those to include ?
 
Ahhh welcome to linux. Actually there is no way to know. You can have
different headers if you have installed different compilers or different
versions of the same compiler, or just some hacks that didn't go well
and left some headers... who knows?
 
Now, you can ask the compiler which headers is it using, if memory
serves gcc had a command line option to show the paths its using.
"Öö Tiib" <ootiib@hot.ee>: Aug 28 11:30PM -0700

On Monday, 29 August 2016 02:20:19 UTC+3, Richard Damon wrote:
> members, you likely need to explicitly define the others, as they WILL
> be created implicitly, and the definition is likely wrong. The default
> constructor does not fall into this category.
 
Does anyone know why the language was designed to create implicitly
functions that are detectable to be likely wrong by so simple check?
The checks about if something is "trivial" or "standard layout" seem
far more complicated. Also, if it was design error then why it
hasn't been repaired?
Vir Campestris <vir.campestris@invalid.invalid>: Aug 29 09:07PM +0100

On 29/08/2016 07:30, Öö Tiib wrote:
> Also, if it was design error then why it
> hasn't been repaired?
 
Most likely because it would break too much existing code. We have a lot
of old baggage in this industry.
 
Andy
Lynn McGuire <lynnmcguire5@gmail.com>: Aug 29 12:06PM -0500

"Unicode"
http://xkcd.com/1726/
 
"Watching the Unicode people try to govern the infinite chaos of human language with consistent technical standards is like watching
highway engineers try to steer a river using traffic signs."
 
As usual, Randall Munroe nails it.
 
Lynn
Daniel <danielaparker@gmail.com>: Aug 29 11:52AM -0700

On Monday, August 29, 2016 at 1:06:54 PM UTC-4, Lynn McGuire wrote:
 
> "Watching the Unicode people try to govern the infinite chaos of human language with consistent technical standards is like watching
> highway engineers try to steer a river using traffic signs."
 
> As usual, Randall Munroe nails it.
 
Has he though? On this one?
 
I think the Unicode people have vastly simplified many people's lives.
 
Admittedly, C++ has badly screwed this up.
 
Daniel
scott@slp53.sl.home (Scott Lurndal): Aug 29 12:53PM

>presumably, continue to advocate:
 
>1) Don't use the unsigned integral types despite the fact that the C++
>standard library is full of their use.
 
Actually, if you're working with unsigned data, use unsigned
types. If you're working with signed data, use signed types.
 
In all cases, use the matching datatype for system interfaces
whether they're in C or C++ headers.
 
>2) Don't use abstract interfaces (as they advocate against using public
>virtual functions).
 
Use abstract interfaces (pure virtual classes) as interfaces (a la Java)
where it makes sense so-to-do.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Aug 29 06:29AM -0700

On Friday, August 26, 2016 at 5:23:09 PM UTC-4, Mr Flibble wrote:
> Some of the idiotic things that regulars of this newsgroup still,
> presumably, continue to advocate:
 
> [snip]
 
Leigh, you could consider using your position of greater knowledge and/or
experience to help teach people who may not know better. Teaching will
invariably accomplish far more than berating.
 
Best regards,
Rick C. Hodgin
Piotr Wyderski <piotr.wyderski.no.spam@gmail.com>: Aug 29 09:13AM +0200

Let there be an arithmetic type T and a class C { T t; };
Under what circumstances the conversions const T* <=>
const C* can be considered legal? Obviously it is not
so if C contains virtual methods. Is sizeof(T) == sizeof(C)
enough from the standard's point of view? Do classes having
this property have a special name/traits in C++ (including C++17)?
 
The application: I have a really big collection of Ts stored on a disk,
but it would be most convenient to access them via the object-oriented
"view" C.
 
Best regards, Piotr
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 29 10:46AM +0200

On 29.08.2016 09:13, Piotr Wyderski wrote:
> const C* can be considered legal? Obviously it is not
> so if C contains virtual methods. Is sizeof(T) == sizeof(C)
> enough from the standard's point of view?
 
No, size has nothing to do with it.
 
Given a C object, the requirement is simply that `t` is the first data
member.
 
 
> Do classes having
> this property have a special name/traits in C++ (including C++17)?
 
Yep, they're called "standard layout" classes.
 
C++11 §9.2/20:
"A pointer to a standard-layout struct object, suitably converted using
a reinterpret_cast, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides) and vice versa."
 
Note that this requires that the object is originally a C.
 
 
> The application: I have a really big collection of Ts stored on a disk,
> but it would be most convenient to access them via the object-oriented
> "view" C.
 
Well, on disk is no problem: just read them into C instances' t members.
No need to do pointer casting.
 
 
Cheers & hth.,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Aug 29 01:33PM +0300

On 29.08.2016 11:46, Alf P. Steinbach wrote:
 
> No, size has nothing to do with it.
 
> Given a C object, the requirement is simply that `t` is the first data
> member.
 
Later he is talking about arrays of T, so it appears the above const T*
really refers to an array, not to a single value. And in arrays sizeof
is very relevant - sizeof is basically defined as the element spacing in
an array.
 
> a reinterpret_cast, points to its initial member (or if that member is a
> bit-field, then to the unit in which it resides) and vice versa."
 
> Note that this requires that the object is originally a C.
 
So it appears that formally casting a T* to a C* is still undefined. I
gather that a perverse implementation might pad T and C in the end to
have equal sizeof-s, but fill the padding with different values which
are checked at run time.
 
>> "view" C.
 
> Well, on disk is no problem: just read them into C instances' t members.
> No need to do pointer casting.
 
He says that the arrays are really large, so he might think of something
like memory mapping the binary file and interpret the content as const
C* instead of const T*. If so, then memory mapping and cast to 'const
T*' are already non-portable enough so that additional cast to const C*
would probably be the safest step here (assuming standard layout, T as
the first member and equal sizeof-s).
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: