Sunday, August 11, 2019

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

James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 10 07:31PM -0400

On 8/10/19 5:46 PM, David Brown wrote:
 
> I already did.
 
> These are from N1570, draft of C11 standard - C++ inherits this from C
> and the C standards are simpler.
 
Actually, no. C++ cross-references the C standard for many purposes. For
instance, it has no description of it's own for virtually the entire C
standard library, incorporating it into the C++ standard library almost
entirely by reference. However, most features in C++ are explicitly
stated in the C++ standard, even when their content is exactly the same
as clauses in the C standard. Here's what the C++ standard says about
alignment:
 
"Object types have alignment requirements (6.9.1, 6.9.2) which place
restrictions on the addresses at which an object of that type may be
allocated. An alignment is an implementation-defined integer value
representing the number of bytes between successive addresses at which a
given object can be allocated. An object type imposes an alignment
requirement on every object of that type; stricter alignment can be
requested using the alignment specifier (10.6.2)." (6.11p1)
 
Pointer conversions are covered by
"If the original pointer value represents the address A of a byte in
memory and A does not satisfy the alignment requirement of T, then the
resulting pointer value is unspecified." (8.2.9p13)
 
While 8.2.9p13 is specifically about static_cast<>, no other way of
converting pointers even addresses performing such pointer conversions,
except insofar as the behavior of reinterpret_cast<> is defined in terms
of corresponding static_cast<> conversions (8.2.10p7). Trying to use any
other method of performing such a conversion has undefined behavior
because the "Standard omits any explicit definition of the behavior..."
(3.27).
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 10 04:37PM -0700

On Saturday, August 10, 2019 at 11:21:30 AM UTC-4, Bonita Montero wrote:
> > More importantly here, it also does not mean you can take pointers
> > to the unaligned members and use them as normal pointers, ...
 
> Quote the part of the standard that says that.
 
You mean you've been saying all this without knowing what the relevant
texts say? I've been assuming all along that you were asserting that
what the standard says doesn't matter - that what actual implementations
do is the only thing that matters, and that you were simply unaware of
the real-world implementations where such code doesn't work.
That you were actually ignorant of clauses 6.11p1 and 8.29p13 of the C++
standard (the relevant details are cited in a recent response of mine to
David's response) hadn't occurred to me.
Keith Thompson <kst-u@mib.org>: Aug 10 05:22PM -0700

David Brown <david.brown@hesbynett.no> writes:
[...]
> The standard says that you can't do unaligned accesses.
 
No, it doesn't. It says that unaligned accesses are undefined behavior.
 
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
David Brown <david.brown@hesbynett.no>: Aug 11 02:24AM +0200

On 11/08/2019 00:59, Ian Collins wrote:
>> inefficient.
 
> Solaris SPARC?
 
> https://blogs.oracle.com/d/on-misaligned-memory-accesses
 
You are missing a critical detail. I said that no compiler would ever
rely on trapping and emulation for handling unaligned accesses to
/packed/ objects. We are not talking about accessing data via a pointer
here - then it makes sense on a processor like the SPARC to assume
accesses are aligned, and handle anything else by crashing or slow
emulation. We are talking about structs with some sort of "packed"
feature. The compiler knows these are unaligned, and would use smaller
accesses. It won't let the program crash - that would be pointless in
the face of a packed struct. It won't rely on seriously slow trap
handling when it knows without doubt that the data is misaligned - it
will use appropriate smaller accesses.
Keith Thompson <kst-u@mib.org>: Aug 10 05:32PM -0700


> That's implementation-defined (6.2.8p1). In C2011 you can determine the
> alignment of a given type under a given implementation by using
> _Alignof(typename).
 
There is a possibly useful distinction that this doesn't capture.
 
For example, on my x86_64 system, gcc has sizeof (int) == 4
and _Alignof (int) == 4. The compiler will, in the absence of
implementation-specific directives, align int objects at 4-byte
boundaries, and any attempt to access an int object that's not
4-byte aligned has undefined behavior.
 
But you can successfully access int objects at odd addresses,
though doing so is likely to be less efficient (but probably more
efficient than accessing it a byte at a time). (Possibly compiler
optimizations might result in surprising and misbehaving code in
such cases.)
 
Would it be useful to be able to query both the alignment at which
objects will be allocated and the (possibly smaller) alignment at
which objects can be accessed without going kaboom?
 
[...]
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
Keith Thompson <kst-u@mib.org>: Aug 10 05:40PM -0700

> legal to take the address of an unaligned packed member - because the
> standard already says that this is undefined behaviour. Thus if a
> compiler wants to say it is allowed, it must document it.
 
If you're going to talk about things that are "legal" or "allowed",
please define what you mean by those words. The standard doesn't
use them.
 
Is the program ill-formed? Is its behavior undefined? Does it
violate a diagnosable rule?
 
There are very few things that are not *allowed* by the language.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
Keith Thompson <kst-u@mib.org>: Aug 10 05:53PM -0700

> On 11/08/2019 00:59, Ian Collins wrote:
>> On 11/08/2019 09:32, David Brown wrote:
[...]
> the face of a packed struct. It won't rely on seriously slow trap
> handling when it knows without doubt that the data is misaligned - it
> will use appropriate smaller accesses.
 
Have you examined the code generated by a SPARC compiler for an
unaligned access to a member of a packed structure? (I'm assuming
that the compiler supports packed structures.)
 
I don't have access to a SPARC system. Perhaps someone who does could
compile this program and compare the code to access obj.x to the code to
access obj.z. The "__attribute__((packed))" syntax works for gcc;
replace it as needed for whatever compiler you're using.
 
#include <iostream>
#include <cstddef>
int main() {
struct foo {
int x;
char y;
int z;
} __attribute__((packed));
foo obj = { 10, '?', 20 };
int x_value = obj.x;
int z_value = obj.z;
std::cout << x_value << " at " << offsetof(struct foo, x) << "\n";
std::cout << z_value << " at " << offsetof(struct foo, z) << "\n";
}
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:23AM +0200

> access.  It might well be that some OS's do, for compatibility with
> binaries for related processors - but your "proof by repeated assertion"
> is getting tedious.
 
I didn't tell that every OS does this.
 
> No compiler would /ever/ rely on trapping and emulation for handling
> unaligned accesses to packed objects - that would be absurdly inefficient.
 
The compiler doesn't care about trapping.
It just compiles unaligned accesse.
 
 
>> This is done only on embedded-platforms with fixed adresses of hardware
>> -registers.
 
> You have no idea what you are talking about.
 
No, I'm knowing what I'm talking about.
 
>> So you're in the context of a certain compiler and hardware.
>> There you don't have to worry about what the standard says.
 
> The standard says that you can't do unaligned accesses.
 
We're talking about certain compilers and not about the standard.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:24AM +0200

> Solaris SPARC?
 
Linux / SPARC also traps unaligned accesses.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:25AM +0200

> You are missing a critical detail.  I said that no compiler would
> ever rely on trapping and emulation for handling unaligned accesses
> to /packed/ objects.
 
Since you are allowed to get an address of such a packed objekt support
for standalone-pointers that do the same must be guaranteed also.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:27AM +0200

> legal to take the address of an unaligned packed member - because the
> standard already says that this is undefined behaviour.  Thus if a
> compiler wants to say it is allowed, it must document it.
 
The standard is irrelevant here since we are talking about secific
implementations with #pragma packed.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:28AM +0200

>>> to  the unaligned members and use them as normal pointers, ...
 
>> Quote the part of the standard that says that.
 
> I already did.
 
I corrected my posting: I said that not the standard is relevant here
but the compiler-documentation since we're talking about a compiler
-specific featre.
David Brown <david.brown@hesbynett.no>: Aug 11 03:41PM +0200

On 11/08/2019 00:22, Bart wrote:
 
> Does C not allow the address of a 32-bit int to be at anything other
> than a multiple of 4, when the machine has byte-addressed memory, even
> when the hardware allows it?
 
The alignment for any given type is determined by the implementation,
which will base it on the target platform's common ABI. Typically,
alignment is based on the size of the type (4-byte types have 4-byte
alignment, etc.) but reduced if the maximum access size for the cpu is
smaller. Thus on a 16-bit target, any type 16-bit or bigger is likely
to be 2 byte aligned. On a 32-bit machine, 16-bit types will be 2-byte
aligned and 32-bit types will be 4-byte aligned. There is some
variation - on a 32-bit machine, you might find that 8-byte doubles are
8-byte aligned, but they might be 4-byte aligned.
 
With that alignment decision made, the C standard explicitly says that
conversions to pointers that result in them being unaligned, are
undefined behaviour - as is dereferencing unaligned pointers. A C
implementation can, of course, give a definition for how it treats
unaligned pointers - but if it does not, then you have to assume that
they are simply not allowed.
David Brown <david.brown@hesbynett.no>: Aug 11 03:52PM +0200

On 11/08/2019 01:31, James Kuyper wrote:
> other method of performing such a conversion has undefined behavior
> because the "Standard omits any explicit definition of the behavior..."
> (3.27).
 
Thank you for being more accurate here. I am not as familiar with the
C++ standards as with the C standards - there are new C++ versions
published faster than I get up to speed with them.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 03:55PM +0200

> With that alignment decision made, the C standard explicitly says
> that conversions to pointers that result in them being unaligned,
> are undefined behaviour - ...
 
Hey, are you still that stupid? We were talking about implementations
with specific support for #pragma pack! On these implementations it
is perfectly legal to take an adress of an unaligned member and such
pointers are indistinguishable from any other unaligned pointer. So
an implemtation that has support for #pragma pack must generally
support unaligned accesses.
David Brown <david.brown@hesbynett.no>: Aug 11 05:26PM +0200

On 11/08/2019 02:53, Keith Thompson wrote:
> std::cout << x_value << " at " << offsetof(struct foo, x) << "\n";
> std::cout << z_value << " at " << offsetof(struct foo, z) << "\n";
> }
 
I don't have a SPARC compiler either - and my favourite resource
<https://godbolt.org> doesn't have it.
 
If someone could compile this code, and also show the instructions used
by the compiler for accessing obj.x and obj.z, that would be nice.
David Brown <david.brown@hesbynett.no>: Aug 11 06:06PM +0200

On 11/08/2019 15:55, Bonita Montero wrote:
 
> Hey, are you still that stupid? We were talking about implementations
> with specific support for #pragma pack! On these implementations it
> is perfectly legal to take an adress of an unaligned member
 
Reference?
 
> and such
> pointers are indistinguishable from any other unaligned pointer.
 
Reference?
 
> So
> an implemtation that has support for #pragma pack must generally
> support unaligned accesses.
 
Reference?
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 06:15PM +0200

>> with specific support for #pragma pack! On these implementations it
>> is perfectly legal to take an adress of an unaligned member
 
> Reference?
 
If the compilers wouldn't allow this, they wouldn't allow taking the
adddress of an unaligned member, but just accessig it with obj.member.
And there must be an information that this isn't allowed in the language
-reference. So you must give the reference that this isn't allowed.
So show me this.
 
>> ... and such
>> pointers are indistinguishable from any other unaligned pointer.
 
> Reference?
 
You can assign to a pointer an aligned and unaligned element on these
compilers. So the compiler can't distinguish this.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 06:40PM +0200

I don't even get a warning compiling that code with MSVC and gcc.
 
#pragma pack(1)
 
struct S
{
char c;
int i;
};
 
void fInc( int *p )
{
++(*p);
}
 
void f()
{
S s;
int i;
int *p;
p = &s.i;
fInc( p );
p = &i;
fInc( p );
}
David Brown <david.brown@hesbynett.no>: Aug 11 06:59PM +0200

On 11/08/2019 18:15, Bonita Montero wrote:
 
>> Reference?
 
> If the compilers wouldn't allow this, they wouldn't allow taking the
> adddress of an unaligned member, but just accessig it with obj.member.
 
 
Ah, the old "it compiles so it must work" argument?
 
 
> And there must be an information that this isn't allowed in the language
> -reference. So you must give the reference that this isn't allowed.
> So show me this.
 
I've given references to say it is undefined at the language level. If
a compiler wants to override that and define its behaviour, fine - it
should document it.
 
 
>> Reference?
 
> You can assign to a pointer an aligned and unaligned element on these
> compilers. So the compiler can't distinguish this.
 
Again, it is all just "it worked when I tried it".
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:03PM +0200

>> If the compilers wouldn't allow this, they wouldn't allow taking the
>> adddress of an unaligned member, but just accessig it with obj.member.
 
> Ah, the old "it compiles so it must work" argument?
 
The compiler can't warn you about everything you're doing wrong.
But this would be clearly recognizable by the compiler and if this
would be an issue you would at least get a warning.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 07:18PM +0200

> <https://godbolt.org> doesn't have it.
> If someone could compile this code, and also show the instructions used
> by the compiler for accessing obj.x and obj.z, that would be nice.
 
Read this, honk:
http://cmynhier.blogspot.com/2008/10/memory-alignment-on-sparc-or-300x.html
But in your head, such compilers might not exist.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Aug 11 11:23AM +0100

Hi,
 
"NoFussJSON" my fast C++ JSON/RJSON parser/generator now supports comments!
 
https://github.com/i42output/neolib/blob/master/include/neolib/json.hpp
 
That is all.
 
/Flibble
 
--
"Snakes didn't evolve, instead talking snakes with legs changed into
snakes." - Rick C. Hodgin
 
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens." –
Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
Bonita Montero <Bonita.Montero@gmail.com>: Aug 11 09:06AM +0200

> But you may be after something else.
 
Yes.
"Öö Tiib" <ootiib@hot.ee>: Aug 11 03:23AM -0700

On Sunday, 11 August 2019 00:45:13 UTC+3, Tim Rentsch wrote:
> I asked because I was curious to know if your confusion about not
> understanding the question had progressed beyond merely being
> uncertain.
 
To where uncertainty about understanding of a problem can progress?
Ignorance about any and all things is default and dominant state
of all minds. So the only progress from there possible seems to
be towards (often vague, often incorrect,) understandings of some
aspects of few things. Did you mean some other "progress"?
 
My current understanding is that states are some kind of "modes
of being" between what can be "transitions". My reading of
OP request was that the "states-and-transitions" have to be
implemented as "state-functions". I expressed that it
feels uncommon. Alf wrote that the goal of it is in textual
simplicity. Plausible. The code (even if terse) would not still
look neither like a state diagram nor like any form of transition
table. So I lost interest in the thread.
 
> > Your habit to answer in useless manner starts to feel
> > strange.
 
> I'm sure other people feel the same way about your answers.
 
My ideas may feel to be useless to many but at least I try
to provide some. I meant that your lack of attempt to express
any thoughts started to feel strange. Have I offended you
somehow?
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: