Monday, November 3, 2014

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

comp.lang.c++@googlegroups.com Google Groups
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com.
scott@slp53.sl.home (Scott Lurndal): Nov 03 03:14PM

>int main()
>{ int i;
> sscanf("0x80000000", "%i", &i);
 
i = strtoull("0x80000000", NULL, 0);
 
handles base 8, 10 and 16 (based on standard prefix interpretation
of leading 0 or 0x for octal/hex respectively). More powerful yet
if you use the middle parameter as well:
 
for example:
 
char *cp;
 
g_dist_bar = strtoull(argv[arg], &cp, 0);
if ((cp == argv[arg]) // Not numeric?
|| (*cp != '\0') // or trailing garbage?
|| (g_dist_bar == 0) // or value == 0
|| (g_dist_bar & 0xfff)) { // or value not congruent to zero modulo 4096.
lp->log("Illegal Distributor Base Address '%s'\n", argv[arg]);
return false;
}
arg++;
 
scott
Christopher Pisz <nospam@notanaddress.com>: Nov 03 09:43AM -0600

On 11/1/2014 2:15 AM, Marcel Mueller wrote:
 
>> std::cout<< "0x"<< std::hex<< i<< std::endl;
 
> This is by far not equivalent. Note that the requirement is to read an
> unsigned number in all common formats (decimal, binary, octal, hex).
 
and streams don't do that?
std::oct
std::hex
std::dec
 
> Using iostream is on of the last things I would do to parse strings.
 
Why? Do you like to reinvent the wheel?
 
> First I would need to copy each string into a stringstream because the
> tokenizer returns slices with start/length rather than individual
> strings.
 
You don't know how to specify a delimiter or a range?
 
 
> Secondly I need to discover the number basis on my own.
 
One would assume you know the number basis or nothing you try is going
to work.
 
> // got it
 
> line points to the start of current line, start and len denote a slice
> in line.
 
Looks like you knew the number basis there ^
 
> Then I can also write my own parser as Rick suggested.
 
If you do that, I hope no one employs you.
There are is enough code out there already where people think they could
do better than the standard library and failed.
David Brown <david.brown@hesbynett.no>: Nov 03 01:14AM +0100

On 02/11/14 23:43, Rick C. Hodgin wrote:
> which I wrote a lengthy reply which can be summed up with this brief
> snippet: "Seriously? Somebody was use THAT feature to affect
> something in main memory? Sounds like it needs refactoring severely."
 
Of /course/ "*tnX++" will "do something" when tnX is declared "volatile
int* tnX". The compiler will generate code to read the memory at *tnX.
It may or may not implement the "++" part - if tnX is not used again,
it will not bother doing so.
 
I don't know all the possible target applications you are thinking of
for RDC, but "volatile" - and accessing memory correctly when volatile
is specified - is vital for all embedded systems, and for many low-level
libraries and OS routines.
 
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 02 06:03PM -0800

On Sunday, November 2, 2014 7:14:46 PM UTC-5, David Brown wrote:
> for RDC, but "volatile" - and accessing memory correctly when volatile
> is specified - is vital for all embedded systems, and for many low-level
> libraries and OS routines.
 
I am well aware of that. When volatile it will behave like normal.
When not volatile, that particular instruction is in error because
it does nothing except increase the value of tnX, but because it has
the dereference operator, it's incorrect in one way or another:
 
(1) Either the developer intended volatile and forgot it, or
(2) It is an improperly coded statement.
 
In either case it is a statement with no valid purpose when it
exists without volatile as a stand-alone.
 
I'm pretty sure I will allow *tnX++; to operate as ++*tnX; when it
is stand-alone. I will do so and generate a particular suppressible
warning when that condition is encountered so that by default the
developer will see the cue, and when he/she recognizes that they
desire the ++*tnX; behavior with that syntax, then they can shut
it off.
 
RDC also has additional features which allow it to integrate with the
IDE and be a continuous compiler. Under that case, individual
instances of warnings can be suppressed, and those suppression
settings can be exported to go along with the source files to other
machines.
 
Best regards,
Rick C. Hodgin
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Nov 02 11:56PM -0700

On Fri, 31 Oct 2014 12:28:32 -0700, Richard Damon
>pointed to (which is then ignored if the phrase is written alone).
 
>Something like (where temp has the same type as tnX):
 
>( (temp = tnX) , (tnx = tnx+1) , (*tnX))
 
If I'm not mistaken, you mean ((temp = tnX), (tnX = tnX + 1), (*temp))
 
Louis
"Tobias Müller" <troplin@bluewin.ch>: Nov 03 07:42AM

> the dereference operator, it's incorrect in one way or another:
 
> (1) Either the developer intended volatile and forgot it, or
> (2) It is an improperly coded statement.
 
IMO it is very important that features of a programming language are
sufficiently orthogonal and independent.
That means, the effect of a combination of features should always be clear
from the individual features.
This will inevitably lead to the fact, that you will find nonsensical
combinations, that are still allowed.
 
Usually such cases can be caught with compiler warnings or lint. But I
don't think it's worth complicating the language rules.
 
And disallowing such cases is one thing, but changing the semantics of an
language feature depending on the context and other features is dangerous
and should be avoided under any circumstances.
 
Tobi
Ben Bacarisse <ben.usenet@bsb.me.uk>: Nov 03 09:43AM

"Rick C. Hodgin" <rick.c.hodgin@gmail.com> writes:
<snip>
> developer will see the cue, and when he/she recognizes that they
> desire the ++*tnX; behavior with that syntax, then they can shut
> it off.
 
When you write the RDC documentation (or even the road map for
development) put this feature front and centre. It will save readers
much time.
 
<snip>
--
Ben.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 03 03:25AM -0800

Ben Bacarisse wrote:
> even the road map for development) put this
> feature front and centre. It will save readers
> much time.
 
Am writing RDC specs draft presently. Lord
willing, I will publish for review this week.
 
Best regards,
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Nov 03 01:18PM +0100

On 03/11/14 03:03, Rick C. Hodgin wrote:
>> is specified - is vital for all embedded systems, and for many low-level
>> libraries and OS routines.
 
> I am well aware of that. When volatile it will behave like normal.
 
No, when "volatile" it will behave like "volatile". When non-volatile,
it will behave like "normal".
 
> (2) It is an improperly coded statement.
 
> In either case it is a statement with no valid purpose when it
> exists without volatile as a stand-alone.
 
Incorrect.
 
Without volatile, the statement "*tnX++;" does not do anything on its
own. But if it were followed by other statements, or if tnX were
returned to the caller, the "tnX++;" part would have an effect. And as
has been pointed out by others, such statements could be generated by
macros.
 
The sensible action is to give a warning message for code like this.
Then the programmer can figure out if he forgot a "volatile", simply
made a mistake somewhere, or if it is the consequence of generated code.
Guessing the programmers intention and changing the meaning of the
statement is the second worst possible action (the worst choice being to
change its meaning without even giving a warning).
 
Even if you could be sure of the developer's /real/ intentions here,
allowing them to write sloppy code that would have a different meaning
elsewhere would encourage bad habits and lead to more problems later.
 
 
 
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 03 05:23AM -0800

On Monday, November 3, 2014 7:18:57 AM UTC-5, David Brown wrote:
 
> > I am well aware of that. When volatile it will behave like normal.
 
> No, when "volatile" it will behave like "volatile". When non-volatile,
> it will behave like "normal".
 
Allow me to restate: When volatile it will behave like [a volatile-declared variable would behave].
 
> returned to the caller, the "tnX++;" part would have an effect. And as
> has been pointed out by others, such statements could be generated by
> macros.
 
The *tnX++; stand-alone does not do anything on its own. It is a corrupt
statement that is malformed when non-volatile stand-alone. It updates tnX,
but it is also in error in so doing because the dereference is impotent.
 
> Guessing the programmers intention and changing the meaning of the
> statement is the second worst possible action (the worst choice being to
> change its meaning without even giving a warning).
 
Existing compilers do this.
 
> Even if you could be sure of the developer's /real/ intentions here,
> allowing them to write sloppy code that would have a different meaning
> elsewhere would encourage bad habits and lead to more problems later.
 
*tnX++; in stand-alone is a special case in RDC. I will treat it as
such, generating a suppressible warning on its stand-alone use. When
used as normal with other code where the dereference has meaning, it
will behave as it would today in C.
 
This behavior will be able to be overridden with the -strict=C option.
 
It's interesting this issue came up. Stuff like this happens to me
from time to time. I find myself riding through it all going "Hmmm,
that's interesting."
 
Best regards,
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Nov 03 02:37PM +0100

On 03/11/14 14:23, Rick C. Hodgin wrote:
>> non-volatile, it will behave like "normal".
 
> Allow me to restate: When volatile it will behave like [a
> volatile-declared variable would behave].
 
Yes, that's correct. Some people seem to think that a compiler should
"do exactly what I tell it and not be smart about it", and thus view
"volatile" behaviour as "normal", and "optimised" behaviour as "too
smart for its own good". I just wanted to be absolutely sure you were
not thinking along those lines.
 
>> could be generated by macros.
 
> The *tnX++; stand-alone does not do anything on its own. It is a
> corrupt statement that is malformed when non-volatile stand-alone.
 
It is neither "corrupt" nor "malformed". It is not particularly useful
in this case, but there are many things that get written in C code that
don't end up producing object code or even affecting the compilation.
 
> It updates tnX, but it is also in error in so doing because the
> dereference is impotent.
 
It may be that the programmer has made an error - and thus a warning
makes sense. But the statement itself is not in error. Doing nothing
is never an error in itself, but can often be an indication that the
programmer has made an error.
 
>> worst choice being to change its meaning without even giving a
>> warning).
 
> Existing compilers do this.
 
Existing compilers generate a warning, if that's what you mean.
Existing compilers do not change the meaning of the code.
 
> such, generating a suppressible warning on its stand-alone use.
> When used as normal with other code where the dereference has
> meaning, it will behave as it would today in C.
 
It is /your/ compiler, of course, but I think you are absolute wrong on
this one. I don't think there is anything more I can say to emphasis
that more strongly - either you understand the importance of consistency
in the language or you will end up with countless more "special cases"
and leave users with little idea of what any particular statement or
expression will do in any particular context. You are at the top of a
slippery slope here, and heading down it fast.
 
 
> This behavior will be able to be overridden with the -strict=C
> option.
 
I assume that this flag will put your compiler into "C mode", and then
you must do your best to follow the standards as closely as you can.
But don't be tempted to have flags that allow different features of RDC
to be interpreted in different ways, as this will cause a lot of confusion.
 
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 03 06:36AM -0800

On Monday, November 3, 2014 8:37:20 AM UTC-5, David Brown wrote:
> [snip]
 
Nobody, Tobias, David, Ben, you've all convinced me. I'm on board with
leaving it as it is and producing a warning.
 
I still may have T-Shirts made up:
 
*tnX++; // :-)
 
Best regards,
Rick C. Hodgin
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 03 12:36AM

On Sun, 02 Nov 2014 16:34:21 +0000
> > *(c-1) = digit_pairs[2*pos];
> > *c = digit_pairs[2*pos+1];
 
> that does not make intToStr any slower
 
And it is also correct. Yours gave rise to undefined behaviour (and I
am surprised your compiler did not warn about it). Did you have -Wall
set?
 
Chris
JiiPee <no@notvalid.com>: Nov 03 12:48AM

On 03/11/2014 00:36, Chris Vine wrote:
> am surprised your compiler did not warn about it). Did you have -Wall
> set?
 
> Chris
 
Am lazy thinking... can you inform me what is the undefined behaviour here?
And yes I used Wall, and did not get warning on that line.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 03 01:30AM

On Mon, 03 Nov 2014 00:48:19 +0000
 
> > Chris
 
> Am lazy thinking... can you inform me what is the undefined behaviour
> here? And yes I used Wall, and did not get warning on that line.
 
Your version gave undefined behaviour because you cannot alias an object
whose dynamic type is a char by dereferencing a pointer to short, in
any version of C or C++. (You can however do the reverse.) So first,
the compiler can simply elide code doing this, and gcc-4.8 and 4.9 is
reputed to do that when provoked with a sufficiently high optimisation
level. Secondly, you may find that object alignments do not match (but
you should be fine on x86).
 
Chris
JiiPee <no@notvalid.com>: Nov 03 01:40AM

On 03/11/2014 01:30, Chris Vine wrote:
> level. Secondly, you may find that object alignments do not match (but
> you should be fine on x86).
 
> Chris
 
yes, I start understanding now... just checked the code and I see now
what is happening there. Ye, maybe it needs to be changed here.... but
otherwise the code seems to be ok.
 
Good observation.. i ll have to change the code.
 
Also I can see that we can make the code even faster by doubling the
lookup table say to see 0-9999 numbers, which would take up memory 40000
char s. That could be a compiling flag maybe to get super fast code with
bigger exe file.
Paavo Helde <myfirstname@osa.pri.ee>: Nov 03 12:04AM -0600

> lookup table say to see 0-9999 numbers, which would take up memory 40000
> char s. That could be a compiling flag maybe to get super fast code with
> bigger exe file.
 
Don't be so sure it will be faster, memory access is often the bottleneck
nowadays. It might even happen that the whole program slows down because
IntToStr() is pushing some useful data out of the caches.
 
To be honest, all this thread seems like an ultimate exercise in premature
optimization. I am pretty sure there will not be many programs where int-
to-string conversion would show up in the profiler. Trading 40000 bytes of
process size to (potentially) speed it up seems dubious, I know there are
people who are whining already about 100 bytes.
 
Cheers
Paavo
Paavo Helde <myfirstname@osa.pri.ee>: Nov 03 12:57AM -0600


> you have the same intToStr time as I have, but I have like 40 secs
> for snprintf. But I have 32 bit computer, so maybe thats the reason.
 
> I ran it again, it took more than 50 secs with snprintf. Dont know....
 
One possibility for 10-time slowdown might be that you have some weird libc
debugging options set up, or some weird locale settings. Check your
environment variables. And of course you can try to profile the program
with e.g. valgrind and see where it spends time.
 
Cheers
Paavo
JiiPee <no@notvalid.com>: Nov 03 07:15AM

On 03/11/2014 06:04, Paavo Helde wrote:
> people who are whining already about 100 bytes.
 
> Cheers
> Paavo
 
I know, but thats why I said it should be under a compile flag, so only
in extreme situations where a big loop is used and there is nothing else
running in the program.
JiiPee <no@notvalid.com>: Nov 03 07:28AM

On 03/11/2014 06:57, Paavo Helde wrote:
> with e.g. valgrind and see where it spends time.
 
> Cheers
> Paavo
 
its a release build, only O3 and s flags on.
But I guess I need to test it next on Visual Studio to see if i get the
same there...
"Öö Tiib" <ootiib@hot.ee>: Nov 02 11:48PM -0800

On Monday, 3 November 2014 09:15:23 UTC+2, JiiPee wrote:
 
> I know, but thats why I said it should be under a compile flag, so
> only in extreme situations where a big loop is used and there is
> nothing else running in the program.
 
Can you picture such real "extreme" situation? I can. Every time
when such text processing shows up in profiler then there is some
sort of needless text communication ... for example JSON layer
between two intensely communicating modules. Even there the
bottle-neck is not usually serialization of ints but dynamic memory management of the little texts. Removing the whole pointless
monkey business text exchange layer itself will always achieve
far better performance gains than optimizing the text composers
and parsers. Using up most of the cache however (40000 is most of
64k L1) will certainly slow it down even more.
Paavo Helde <myfirstname@osa.pri.ee>: Nov 03 02:16AM -0600


> I know, but thats why I said it should be under a compile flag, so
> only in extreme situations where a big loop is used and there is
> nothing else running in the program.
 
This has not much to do with the compiler, sprintf is a C standard
library function. The C standard library is meant as a general-purpose
library making a decent choice of different tradeoffs (like speed vs
memory usage vs development and maintenance efforts, etc) so that it is
good enough for most usage cases. As a result of tradeoffs it cannot be
the best choice in all situations.
 
In particular, sprintf() is defined as a locale-dependent function, with
all the legacy and drawbacks associated with it. It is also defined as a
function driven by a separate minilanguage and doing the runtime
interpretation of that. These two facts already basically exclude the
possibility that it could be the fastest tool around, so if some program
requires maximum performance in this area, it cannot use sprintf anyway,
regardless of whether it can be finetuned by some compiler switches or
not.
 
In special corner cases like your hypothetical program doing only
zillions of int-string conversions one may need to use special custom
functions or libraries. You know, there are lots of special purpose
libraries in C and C++. This special IntToStr() function looks like a
good candidate for such a library.
 
All this does not mean that the standard C library version of sprintf()
could not be made better. With glibc everybody can actually do that in
principle, it's an open-source collaborative project. The toughest part
would probably be reaching an agreement about what is "better".
 
Cheers
Paavo
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 03 12:58AM

On Sat, 1 Nov 2014 09:55:20 -0700 (PDT)
> I am explicitly a Christian offering this product unto the Lord, and
> unto men. I am not doing it for other reasons. As such, I convey
> that through my product.
 
At least this part of your post is semi-on-topic, since it does relate
to some code you are developing with C++ (I think). If so, we should be
grateful for that at least.
 
However, "unto" has been archaic in English for many centuries now.
"To" is a perfectly good modern substitute. Presumably your usage stems
from an obsession with the King James translation of the bible into
English. Even at the time of the translation, the word was at least
formal, if not already archaic then. (There are much better translations
available now of course.)
 
On an English language news group, amongst whose users there are many
posters who do not have English as their first language, you might
convey your thoughts better about your project if you were to use
language that people have spoken in the last few centuries (outside any
of the weird American religious sects that you may belong to).
 
Chris
JiiPee <no@notvalid.com>: Nov 02 11:53PM

On 02/11/2014 08:40, Jorgen Grahn wrote:
> One API I'm using has
 
> typedef char* String;
> typedef const char* ConstString;
 
imo this is just bad. char* is not a string...its just not....
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 03 12:15AM

On Sun, 02 Nov 2014 08:05:19 +0100
> happen if we could do in english:
 
> using yes = no;
> using no = yes;
 
You admit to not knowing C++. It appears that you don't know C
either. In this usage, 'using' is just another spelling (and ordering)
of typedef. Both alias types.
 
Chris
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: