Tuesday, May 21, 2019

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

Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: May 21 11:46PM +0100

Hi!
 
neos progress report time!
 
neos now fully parses my "neoscript" fibonacci example/test program!
Semantic concepts are emitted now all that needs to be done is to add
semantic concept folding and semantic concept bytecode emission so I can
run the program!
 
Compilation session (scroll to bottom to see test program source code):
 
neos 1.0.0.0 ED-209
Loading schema 'neoscript.neos'...
Language: Default neoGFX scripting language
Version: 1.0.0
Copyright (C) 2019 Leigh Johnston
emit: <3> language.keyword ()
emit: <4> string.utf8.character.alpha (n)
emit: <5> string.utf8.character.alpha (e)
emit: <5> string.utf8.character.alpha (o)
emit: <5> string.utf8.character.alpha (s)
emit: <5> string.utf8.character.period (.)
emit: <6> string.utf8.character.alpha (s)
emit: <7> string.utf8.character.alpha (t)
emit: <7> string.utf8.character.alpha (r)
emit: <7> string.utf8.character.alpha (i)
emit: <7> string.utf8.character.alpha (n)
emit: <7> string.utf8.character.alpha (g)
emit: <4> module.package.name ()
emit: <3> module.package.import ()
emit: <3> module.package.instantiate ()
emit: <3> language.keyword ()
emit: <4> string.utf8.character.alpha (n)
emit: <5> string.utf8.character.alpha (e)
emit: <5> string.utf8.character.alpha (o)
emit: <5> string.utf8.character.alpha (s)
emit: <5> string.utf8.character.period (.)
emit: <6> string.utf8.character.alpha (s)
emit: <7> string.utf8.character.alpha (t)
emit: <7> string.utf8.character.alpha (r)
emit: <7> string.utf8.character.alpha (e)
emit: <7> string.utf8.character.alpha (a)
emit: <7> string.utf8.character.alpha (m)
emit: <4> module.package.name ()
emit: <3> module.package.import ()
emit: <3> module.package.instantiate ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (t)
emit: <6> string.utf8.character.alpha (o)
emit: <6> string.utf8.character.underscore (_)
emit: <6> string.utf8.character.alpha (s)
emit: <6> string.utf8.character.alpha (t)
emit: <6> string.utf8.character.alpha (r)
emit: <6> string.utf8.character.alpha (i)
emit: <6> string.utf8.character.alpha (n)
emit: <6> string.utf8.character.alpha (g)
emit: <5> language.identifier ()
emit: <10> string.utf8.character.alpha (x)
emit: <10> language.identifier ()
emit: <9> language.function.parameter ()
emit: <11> language.type.i32 ()
emit: <7> language.function.parameters ()
emit: <10> language.type.string ()
emit: <9> language.function.return ()
emit: <4> language.function.signature ()
emit: <4> language.function.import ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (t)
emit: <6> string.utf8.character.alpha (o)
emit: <6> string.utf8.character.underscore (_)
emit: <6> string.utf8.character.alpha (i)
emit: <6> string.utf8.character.alpha (n)
emit: <6> string.utf8.character.alpha (t)
emit: <6> string.utf8.character.alpha (e)
emit: <6> string.utf8.character.alpha (g)
emit: <6> string.utf8.character.alpha (e)
emit: <6> string.utf8.character.alpha (r)
emit: <5> language.identifier ()
emit: <10> string.utf8.character.alpha (s)
emit: <10> language.identifier ()
emit: <9> language.function.parameter ()
emit: <11> language.type.string ()
emit: <7> language.function.parameters ()
emit: <10> language.type.i32 ()
emit: <9> language.function.return ()
emit: <4> language.function.signature ()
emit: <4> language.function.import ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (i)
emit: <6> string.utf8.character.alpha (n)
emit: <6> string.utf8.character.alpha (p)
emit: <6> string.utf8.character.alpha (u)
emit: <6> string.utf8.character.alpha (t)
emit: <5> language.identifier ()
emit: <10> string.utf8.character.alpha (s)
emit: <10> language.identifier ()
emit: <9> language.function.parameter ()
emit: <11> language.keyword ()
emit: <10> language.function.parameter.direction.out ()
emit: <12> language.type.string ()
emit: <7> language.function.parameters ()
emit: <4> language.function.signature ()
emit: <4> language.function.import ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (p)
emit: <6> string.utf8.character.alpha (r)
emit: <6> string.utf8.character.alpha (i)
emit: <6> string.utf8.character.alpha (n)
emit: <6> string.utf8.character.alpha (t)
emit: <5> language.identifier ()
emit: <10> string.utf8.character.alpha (s)
emit: <10> language.identifier ()
emit: <9> language.function.parameter ()
emit: <11> language.keyword ()
emit: <10> language.function.parameter.direction.in ()
emit: <12> language.type.string ()
emit: <7> language.function.parameters ()
emit: <4> language.function.signature ()
emit: <4> language.function.import ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (a)
emit: <6> string.utf8.character.alpha (d)
emit: <6> string.utf8.character.alpha (d)
emit: <5> language.identifier ()
emit: <10> string.utf8.character.alpha (x)
emit: <10> language.identifier ()
emit: <9> language.function.parameter ()
emit: <12> string.utf8.character.alpha (y)
emit: <12> language.identifier ()
emit: <11> language.function.parameter ()
emit: <13> language.type.i32 ()
emit: <7> language.function.parameters ()
emit: <10> language.type.i32 ()
emit: <9> language.function.return ()
emit: <4> language.function.signature ()
emit: <8> language.keyword ()
emit: <13> string.utf8.character.alpha (x)
emit: <13> language.identifier ()
emit: <12> math.expression.operand ()
emit: <15> string.utf8.character.alpha (y)
emit: <15> language.identifier ()
emit: <14> math.expression.operand ()
emit: <10> math.operator.add ()
emit: <9> math.expression ()
emit: <9> language.function.return ()
emit: <7> language.statement ()
emit: <5> language.function.scope ()
emit: <4> language.function ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (f)
emit: <6> string.utf8.character.alpha (i)
emit: <6> string.utf8.character.alpha (b)
emit: <5> language.identifier ()
emit: <10> string.utf8.character.alpha (x)
emit: <10> language.identifier ()
emit: <9> language.function.parameter ()
emit: <11> language.type.i32 ()
emit: <7> language.function.parameters ()
emit: <10> language.type.i32 ()
emit: <9> language.function.return ()
emit: <4> language.function.signature ()
emit: <8> language.keyword ()
emit: <17> string.utf8.character.alpha (x)
emit: <17> language.identifier ()
emit: <16> math.expression.operand ()
emit: <13> math.expression ()
emit: <12> boolean.expression.operand ()
emit: <18> math.universal.number.digit (1)
emit: <18> math.universal.number ()
emit: <18> math.expression.operand ()
emit: <15> math.expression ()
emit: <14> boolean.expression.operand ()
emit: <12> boolean.operator.relational.equal ()
emit: <10> boolean.expression ()
emit: <13> language.keyword ()
emit: <17> math.universal.number.digit (1)
emit: <17> math.universal.number ()
emit: <17> math.expression.operand ()
emit: <14> math.expression ()
emit: <14> language.function.return ()
emit: <12> language.statement ()
emit: <11> logic.operator.if ()
emit: <14> language.keyword ()
emit: <16> language.keyword ()
emit: <21> string.utf8.character.alpha (a)
emit: <22> string.utf8.character.alpha (d)
emit: <22> string.utf8.character.alpha (d)
emit: <21> language.identifier ()
emit: <27> string.utf8.character.alpha (f)
emit: <28> string.utf8.character.alpha (i)
emit: <28> string.utf8.character.alpha (b)
emit: <27> language.identifier ()
emit: <33> string.utf8.character.alpha (x)
emit: <33> language.identifier ()
emit: <32> math.expression.operand ()
emit: <34> math.universal.number.digit (1)
emit: <34> math.universal.number ()
emit: <34> math.expression.operand ()
emit: <30> math.operator.subtract ()
emit: <29> math.expression ()
emit: <28> language.function.argument ()
emit: <29> language.function.call ()
emit: <26> math.expression.operand ()
emit: <23> math.expression ()
emit: <22> language.function.argument ()
emit: <29> string.utf8.character.alpha (f)
emit: <30> string.utf8.character.alpha (i)
emit: <30> string.utf8.character.alpha (b)
emit: <29> language.identifier ()
emit: <35> string.utf8.character.alpha (x)
emit: <35> language.identifier ()
emit: <34> math.expression.operand ()
emit: <36> math.universal.number.digit (2)
emit: <36> math.universal.number ()
emit: <36> math.expression.operand ()
emit: <32> math.operator.subtract ()
emit: <31> math.expression ()
emit: <30> language.function.argument ()
emit: <31> language.function.call ()
emit: <28> math.expression.operand ()
emit: <25> math.expression ()
emit: <24> language.function.argument ()
emit: <25> language.function.call ()
emit: <20> math.expression.operand ()
emit: <17> math.expression ()
emit: <17> language.function.return ()
emit: <15> language.statement ()
emit: <14> logic.operator.else ()
emit: <7> language.statement ()
emit: <5> language.function.scope ()
emit: <4> language.function ()
emit: <3> language.keyword ()
emit: <4> language.keyword ()
emit: <5> string.utf8.character.alpha (m)
emit: <6> string.utf8.character.alpha (a)
emit: <6> string.utf8.character.alpha (i)
emit: <6> string.utf8.character.alpha (n)
emit: <5> language.identifier ()
emit: <4> language.function.signature ()
emit: <8> string.utf8.character.alpha (s)
emit: <8> language.identifier ()
emit: <7> language.function.local ()
emit: <9> language.type.string ()
emit: <5> language.function.locals ()
emit: <5> language.function.locals ()
emit: <13> string.utf8.character.alpha (i)
emit: <14> string.utf8.character.alpha (n)
emit: <14> string.utf8.character.alpha (p)
emit: <14> string.utf8.character.alpha (u)
emit: <14> string.utf8.character.alpha (t)
emit: <13> language.identifier ()
emit: <19> string.utf8.character.alpha (s)
emit: <19> language.identifier ()
emit: <18> math.expression.operand ()
emit: <15> math.expression ()
emit: <14> language.function.argument ()
emit: <15> language.function.call ()
emit: <12> math.expression.operand ()
emit: <9> math.expression ()
emit: <8> language.statement ()
emit: <9> language.function.return ()
emit: <8> language.statement ()
emit: <13> string.utf8.character.alpha (p)
emit: <14> string.utf8.character.alpha (r)
emit: <14> string.utf8.character.alpha (i)
emit: <14> string.utf8.character.alpha (n)
emit: <14> string.utf8.character.alpha (t)
emit: <13> language.identifier ()
emit: <19> string.utf8.character.alpha (s)
emit: <19> language.identifier ()
emit: <18> math.expression.operand ()
emit: <22> string.utf8.character (:)
emit: <22> string.utf8.character ( )
emit: <21> string.utf8 ()
emit: <20> math.expression.operand ()
emit: <16> math.operator.add ()
emit: <23> string.utf8.character.alpha (t)
emit: <24> string.utf8.character.alpha (o)
emit: <24> string.utf8.character.underscore (_)
emit: <24> string.utf8.character.alpha (s)
emit: <24> string.utf8.character.alpha (t)
emit: <24> string.utf8.character.alpha (r)
emit: <24> string.utf8.character.alpha (i)
emit: <24> string.utf8.character.alpha (n)
emit: <24> string.utf8.character.alpha (g)
emit: <23> language.identifier ()
emit: <29> string.utf8.character.alpha (f)
emit: <30> string.utf8.character.alpha (i)
emit: <30> string.utf8.character.alpha (b)
emit: <29> language.identifier ()
emit: <35> string.utf8.character.alpha (t)
emit: <36> string.utf8.character.alpha (o)
emit: <36> string.utf8.character.underscore (_)
emit: <36> string.utf8.character.alpha (i)
emit: <36> string.utf8.character.alpha (n)
emit: <36> string.utf8.character.alpha (t)
emit: <36> string.utf8.character.alpha (e)
emit: <36> string.utf8.character.alpha (g)
emit: <36> string.utf8.character.alpha (e)
emit: <36> string.utf8.character.alpha (r)
emit: <35> language.identifier ()
emit: <41> string.utf8.character.alpha (s)
emit: <41> language.identifier ()
emit: <40> math.expression.operand ()
emit: <37> math.expression ()
emit: <36> language.function.argument ()
emit: <37> language.function.call ()
emit: <34> math.expression.operand ()
emit: <31> math.expression ()
emit: <30> language.function.argument ()
emit: <31> language.function.call ()
emit: <28> math.expression.operand ()
emit: <25> math.expression ()
emit: <24> language.function.argument ()
emit: <25> language.function.call ()
emit: <22> math.expression.operand ()
emit: <18> math.operator.add ()
emit: <15> math.expression ()
emit: <14> language.function.argument ()
emit: <15> language.function.call ()
emit: <12> math.expression.operand ()
emit: <9> math.expression ()
emit: <8> language.statement ()
emit: <9> language.function.return ()
emit: <8> language.statement ()
emit: <6> language.function.scope ()
emit: <5> language.function ()
Compilation time: 326.358ms
neoscript]cte 0
neoscript]l examples/neoscript/fibonacci.neo
Compilation time: 31.001ms
neoscript]list
-- neoscript example: Fibonacci
 
using neos.string;
using neos.stream;
 
import fn to_string(x : i32) -> string;
import fn to_integer(s : string) -> i32;
import proc input(s : out string);
import proc print(s : in string);
 
-- functions are pure
def fn add(x, y : i32) -> i32
{
return x + y;
}
def fn fib(x : i32) -> i32
{
if (x = 1)
return 1;
else
return add(fib(x-1), fib(x-2));
}
 
-- procedures are impure
def proc main()
s : string;
{
input(s);
print(s + ": " + to_string(fib(to_integer(s))));
}
neoscript]
 
I am quite happy with a compilation speed of 30ms for this but there are
no doubt further optimizations I can make.
 
/Flibble
 
--
"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."
Horizon68 <horizon@horizon.com>: May 21 03:27PM -0700

Hello..
 
 
About my new invention that is a Fast Mutex..
 
I have just invented a Fast mutex with the following characteristics:
 
1- Starvation-free
2- Good fairness
3- It reduces very efficiently the cache coherence traffic
4- Very good fast path performance
 
But can you please run the following windows 64-bit benchmark of it and
report to me the results, but you need to have 8 cores or more, here is
the benchmark of mine:
 
https://sites.google.com/site/scalable68/benchmark-of-my-new-fast-mutex
 
 
 
Thank you,
Amine Moulay Ramdane.
Horizon68 <horizon@horizon.com>: May 21 03:32PM -0700

On 5/21/2019 3:27 PM, Horizon68 wrote:
 
> https://sites.google.com/site/scalable68/benchmark-of-my-new-fast-mutex
 
> Thank you,
> Amine Moulay Ramdane.
 
 
And please report also to me how many cores you have.
 
 
Thank you,
Amine Moulay Ramdane.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 21 08:08PM +0100

On Tue, 21 May 2019 20:47:01 +0200
> > do with a shortcoming of C++03 Herb Sutter and Andrei Alexandrescu
> > recommended used `static_cast` in their old coding guidelines book.
 
> static_cast, reinterpret_cast or C-style-cast - pure syntatic sugar.
 
That depends on what you mean by "syntactic sugar". static_cast will
carry out pointer adjustment so it can be used to navigate an
inheritance graph correctly. reinterpret_cast won't - it is purely a
reinterpretation of a bit pattern.
Bart <bc@freeuk.com>: May 21 06:24PM +0100

On 21/05/2019 16:28, Chris Vine wrote:
> designer involving trade-offs between amongst other things optimization
> opportunities, convenience to the programmer, language complexity and
> safety.
 
Yes, but in this case what someone may want to do could be completely
reasonable in itself, and could be well-defined on the processors they
know their program will run on.
 
When you look at the reasons why C and also C++ have made certain things
UB, you could well find they don't apply in your case.
 
Now, I've frequently written code in one language, which works perfectly
well as native code, but it hits UB if I auto-translate to C. There are
actually more problems generating C source as a target, then generating ASM.
 
(And actually, when I briefly tried to target C++, there were even more
problems.)
blt_1d31iu1a18@dxekg86ut76lwln.org: May 21 07:28PM

On Tue, 21 May 2019 11:49:13 +0100
 
>The "it" which doesn't work is type punning through casting pointers.
>Your silly toy code with undefined behaviour proves absolutely
>nothing. An example has already been given up-thread of the
 
Me: "The code works on every compiler I've ever tried"
 
You: "But it won't work on modern compilers with optimisation!"
 
Me: [Shows code doing exactly that with 2 compilers]
 
You: "Oh well, its just silly toy code blah blah feeble backpedal blah blah"
 
>differences which can arise in code emitted, depending on whether the
>-fno-strict-aliasing switch is applied or not.
 
And someone else explained what happened which was nothing to do with type
punning.
 
>"ignore that because although gcc warns that it breaks strict aliasing,
>clang doesn't". If that is your approach to programming then "crap
>code" seems like too mild a description.
 
The code works and always has done. A pointer is always the same size for
every type and always will be.
 
However, feel free to provide a proper example where it fails or you can just
keep on farting out indignant hot air. You choice.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 21 08:47PM +0100

On Tue, 21 May 2019 19:28:17 +0000 (UTC)
> >-fno-strict-aliasing switch is applied or not.
 
> And someone else explained what happened which was nothing to do with type
> punning.
 
Nonsense - see below.
 
> every type and always will be.
 
> However, feel free to provide a proper example where it fails or you can just
> keep on farting out indignant hot air. You choice.
 
No, still wrong I am afraid. I repeat: "The 'it' which doesn't work is
type punning through casting pointers." It doesn't work because it
doesn't work, end of story. Your bluster that when the standard says
incorrect aliasing gives rise to undefined behaviour it really means
that it works fine in your toy programs, is crap.
 
And the example to which I referred was corrected (20 May 2019 21:49:30
+0200) and did demonstrate the strict aliasing issue.
 
If you want another example, there is one in the posting of another
person:
 
int foo( float *f, int *i ) {
*i = 1;
*f = 0.f;

return *i;
}
 
int main() {
int x = 0;

std::cout << x << "\n"; // Expect 0
x = foo(reinterpret_cast<float*>(&x), &x);
std::cout << x << "\n"; // Expect 0?
}
 
You will find many similar examples in articles on the internet about
strict aliasing.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 21 08:01PM +0200

On 21.05.2019 18:20, Paavo Helde wrote:
> *fp = 1.0f;
 
> and one should use placement new instead:
 
> new (p) float {1.0f} ;
 
The initialization of `fp` wouldn't compile as C++, but let's assume a
`static_cast` or `reinterpret_cast` there. I favor the latter since it
communicates better to the reader, but I believe for reasons having to
do with a shortcoming of C++03 Herb Sutter and Andrei Alexandrescu
recommended used `static_cast` in their old coding guidelines book.
 
 
> > Now that I find hard to crasp. If this is true, how is it even possible
> to write e.g. a custom memory allocator?
 
Magic is indeed performed in a `new` expression: it transforms a `void*`
produced by an allocator function, to a typed pointer.
 
Another place this magic occurs, is in the member functions of a
`std::allocator`. At least in C++03. I'm not as up-to-date as I should
be to participate in C++ discussions.
 
Anyway, even placement `new` doesn't save one from UB when there is an
object other than byte in that memory chunk, and one obtains a pointer
to it of an unrelated pointee type. Wham bang, you're formally dead.
 
On the other hand, when there is no object of type other than bytes,
then `reinterpret_cast` is technically good and so is placement `new`.
 
 
> std::vector<float>::data())? Do I really need to perform a dummy
> placement new in the beginning of the memory block, to obtain a valid
> float* pointer?
 
Nah, just FUD.
 
 
Cheers!,
 
- Alf
scott@slp53.sl.home (Scott Lurndal): May 21 07:53PM

>On Tue, 21 May 2019 11:49:13 +0100
 
>The code works and always has done. A pointer is always the same size for
>every type and always will be.
 
Actually at least one major processor vendor has been thinking about
changing this in the future.....
 
And it certainly wasn't true in the past.
Bonita Montero <Bonita.Montero@gmail.com>: May 21 08:47PM +0200

> communicates better to the reader, but I believe for reasons having to
> do with a shortcoming of C++03 Herb Sutter and Andrei Alexandrescu
> recommended used `static_cast` in their old coding guidelines book.
 
static_cast, reinterpret_cast or C-style-cast - pure syntatic sugar.
Bart <bc@freeuk.com>: May 21 07:56PM +0100

On 21/05/2019 19:02, Paavo Helde wrote:
 
>> Now, I've frequently written code in one language, which works perfectly
>> well as native code, but it hits UB if I auto-translate to C.
 
> Seems like a bug in the auto-translator.
 
Just a mismatch of languages, even though C in this case superficially
works the same way.
 
C as an intermediate language, even though it is very frequently used
for that purpose, leaves a lot to be desired.
 
>> actually more problems generating C source as a target, then generating
>> ASM.
 
> Which ASM? All the 72 architectures covered by gcc?
 
The ones I had in mind were x64 and ARM64. I think I decided it would be
simpler to target those two than to try and generate C code which would
always compile warning-free and UB-free.
 
Are there are any others I'm likely to be able to program in consumer
equipment?
 
I think it is quite common for applications to only need to run on a
small number of architectures, but not want to be inconvenienced by a
language designed to work with every conceivable architecture, past,
present and future, and which therefore have to designate as UB,
behaviour which cannot be guaranteed to work across all of them.
 
 
>> (And actually, when I briefly tried to target C++, there were even more
>> problems.)
 
> I bet.
 
I haven't tried it for a while. If I try it know on a smallish 3200-line
generated-C program, I get the following number of lines of errors and
warnings:
 
No options (just -c) Lots of -W options
 
gcc 0 lines 2900 lines
g++ 1150 lines 2850 lines
 
Typical error from the 1150-line output is:
 
jpeg.c:420:5: error: invalid conversion from 'int64 (*)(jpeg_stream*)'
{aka 'long long int (*)(jpeg_stream*)'} to 'void*' [-fpermissive]
 
(Actually, this line is nothing to do with the application, but this
language generates some metadata which includes an array of pointers to
all functions used in the program. Since every function would have its
own pointer type which depends on its signature, what should be the
array element type?
 
As far as I'm concerned, any function pointer can be stored within the
same space as a void* pointer on all targets I want this to run on. It
should be a non-issue.)
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 21 08:04PM +0100

On Tue, 21 May 2019 19:20:46 +0300
> std::vector<float>::data())? Do I really need to perform a dummy
> placement new in the beginning of the memory block, to obtain a valid
> float* pointer?
 
Looking at operator new() rather than malloc() (both of which do pretty
much the same thing), the C++14 standard (§3.7.4.1/2) says
 
"The pointer returned shall be suitably aligned so that it can be
converted to a pointer of any complete object type with a fundamental
alignment requirement (3.11) and then used to access the object or
array in the storage allocated (until the storage is explicitly
deallocated by a call to a corresponding deallocation function)."
 
So you can use the storage provided by operator new() to access an
object constucted in that storage. The dynamic type of the allocated
storage is in effect the type of the first object constructed in it
(here, a float). So for trivial types (which do not need to execute a
constructor and destructor) I don't think it is necessary to use
placement new - I think you can just assign or memcpy() into the memory.
That is a feature of trivial types.
 
It would be a ridiculous interpretation of the standard that malloc()
operates differently. Footnote 36 itself says:
 
"The intent is to have operator new() implementable by calling
std::malloc() or std::calloc(), so the rules are substantially the
same. C++ differs from C in requiring a zero request to return a
non-null pointer."
 
The dynamic type of malloc()'ed memory must surely, as in the case of
the effective type in C, arise upon first construction of an object in
that memory, either by placement new (C++) or assignment or memcpy()
(C, and C++ trivial types).
 
Chris
David Brown <david.brown@hesbynett.no>: May 21 11:57PM +0200

On 21/05/2019 16:45, Bart wrote:
>> and their standards that matter.
 
> But how can code that expresses exactly the same thing be fine in one
> language and not in another?
 
That's a meaningless question. If the code expresses exactly the same
thing in different languages, then it is fine in those languages. Code
that does not have defined behaviour in a language is not expressing
anything at all - totally regardless of whether similar looking code has
a meaning in a different language.
 
 
 
> And here apparently the same code can be also be fine in a particular
> dialect of C or C++, or even using a particular set of compiler options,
> but be 'crap' when someone changes the compiler or option.
 
Now you are beginning to understand!
 
Code has to be written in a programming language. If the words and
symbols you use don't make sense in that language, then the code is
wrong - even if the same words and symbols make sense in a different
language or different language variation.
 
 
 
>   11111110111001100110011001100110011001100110011001100110011010
 
> No faffing about with unions or *(int64_t*)&x casts (which won't work on
> 0.1), which apparently have UB anyway, or memcpy.)
 
Your language is not C. In C, you do this differently - as you can't
access the float via a pointer to a 64-bit integer type, and there is no
pre-defined method of printing in binary anyway. Why does it bother you
so much that you have to write different things in different languages?
 
>> your language is "better" than C?
 
> It's 'better' in that it allows this sort of obvious stuff that people
> want to write, while C doesn't.
 
I don't believe that many people /do/ want to write this sort of thing,
and it is certainly not "obvious". (The implementation, and assembly
level, is obvious. But we are not programming in assembly.)
 
I can appreciate that /you/ want to use concepts like this, and thus it
makes sense to have it as a feature in your personal language. But I
have long ago given up trying to understand /why/ you want to do it or
why you find these things so useful in your coding. Perhaps they just
happen to be helpful in writing compilers and translators.
David Brown <david.brown@hesbynett.no>: May 22 12:13AM +0200

On 21/05/2019 20:56, Bart wrote:
 
>> Seems like a bug in the auto-translator.
 
> Just a mismatch of languages, even though C in this case superficially
> works the same way.
 
In other words, bugs in the auto-translator. The flaws are in the
design and specification, rather than the implementation, but they are
bugs nonetheless.
 
In order to translate code from one language to another, you need to
understand both languages. And you need to generate correct and valid
code - not something that looks a bit like what you would have liked the
target language to be.
 
 
> C as an intermediate language, even though it is very frequently used
> for that purpose, leaves a lot to be desired.
 
It is fine as a target language, but you need to generate correct C
code. (Alternatively, you need to generate "C for this compiler, this
target and these options" code - and be honest about it. That is a
perfectly reasonable solution, and the one used by most code generators.)
 
Other people who write code generators or translators that produce C
manage it. And when their generated code has flaws, they blame their
generators - not the language.
 
 
> The ones I had in mind were x64 and ARM64. I think I decided it would be
> simpler to target those two than to try and generate C code which would
> always compile warning-free and UB-free.
 
You understand how assembly works. You are willing to use features of
assemblers. You don't understand how C works. You are unwilling to use
many features of the language. It is not surprising that you find
generating assembly easier than generating C code.
 
> Are there are any others I'm likely to be able to program in consumer
> equipment?
 
Since your languages and tools are for you alone, it is up to you to
answer that one.
 
> language designed to work with every conceivable architecture, past,
> present and future, and which therefore have to designate as UB,
> behaviour which cannot be guaranteed to work across all of them.
 
I agree that code rarely has to be very portable. Of course, I disagree
about your characterisation of UB - in particular, it does not make
sense to suggest that code with undefined behaviour could work at all.
By the meaning of the words, code with undefined behaviour does not have
any definition of what it is supposed to do, and therefore cannot be
considered to "work". At best, you mean the code should do what it
looks like you think it should do. That might be okay to a human
reader, but computers are fussy about definitions.
 
 
> As far as I'm concerned, any function pointer can be stored within the
> same space as a void* pointer on all targets I want this to run on. It
> should be a non-issue.)
 
C and C++ do not share your opinion - and you are asking the compiler to
treat your code as (approximately) standard C or C++. However, gcc (and
all other serious compilers) give you a lot of flexibility about
choosing warnings and other options, precisely to let you tune the
details of the language you want. If you want to generate code that
only works on platforms where you can store a function pointer in a
void* pointer (though I can't imagine why it would be useful), you can
tune your options to suit. Perhaps try with "-fpermissive" ?
David Brown <david.brown@hesbynett.no>: May 22 12:18AM +0200

On 21/05/2019 21:53, Scott Lurndal wrote:
 
> Actually at least one major processor vendor has been thinking about
> changing this in the future.....
 
> And it certainly wasn't true in the past.
 
It is not true at the moment either. There are more processors around
than just x86 and ARM. (I know you, Scott, know this - I am expanding
on your post, not correcting it.)
 
And of course, the size of pointers has absolutely /nothing/ to do with
the undefined nature of trying to access an object through a pointer to
a different type.
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: