Wednesday, November 11, 2015

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

cdalten@gmail.com: Nov 10 08:59PM -0800

I think you need to lay off the ganja when coding.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 11 07:48AM +0100

> I think you need to lay off the ganja when coding.
 
Usenet (this is Usenet) is a distributed service, with no guaranteed
delivery and where articles can be received out of order.
 
Therefore it's important that you QUOTE what you're referring to.
 
For those who don't see that context, Chad is referring to this code:
 
#include <iostream>
#include <string>
using namespace std;
 
auto main( int, char** args ) -> int
{
int const max = stoi( args[1] );
wstring word, separator, line;
while( wcin >> word ) {
if( int(line.length() + 1 + word.length()) > max ) {
wcout << line << endl;
line.clear();
}
line += (line.length()? L" " : L"") + word;
}
wcout << line << endl;
}
 
So, Chad, can you elaborate on why you think this is coded under the
influence of marihuana? What in particular strikes you as odd? Or what
is it that appears difficult to understand?
 
Apparently you're a novice C++ programmer, having started some years ago
with Python and Ruby. Remember that C++ is not just a different language
than Python or Ruby, but is a different /kind/ of language. We can help
you learn, in fact it's what this group is all about, but to do that we
need to know more than just that you find some code odd.
 
 
Cheers & hth.,
 
- Alf
Ian Collins <ian-news@hotmail.com>: Nov 11 08:22PM +1300

Alf P. Steinbach wrote:
 
 
> auto main( int, char** args ) -> int
> {
> int const max = stoi( args[1] );
 
For on who likes to (mis)use auto, there's a lost opportunity...
 
--
Ian Collins
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 11 08:54AM +0100

On 11/11/2015 8:22 AM, Ian Collins wrote:
>> {
>> int const max = stoi( args[1] );
 
> For on who likes to (mis)use auto, there's a lost opportunity...
 
If the type had been specified explicitly in the initializer, then I
would have used `auto` in order to have a single uniform convention for
that and in order to minimize redundancy, the DRY principle. E.g.
 
auto const p = reinterpret_cast<Foobar*>( zzz );
 
Likewise if the specific type had been irrelevant, e.g.
 
for( auto it = c.begin(); it != c.end(); ++it ) { ... }
 
I try to use `auto` for all function declarations, but I discovered that
in some cases current compilers don't accept that unless one uses a
logically redundant type naming. E.g.
 
std::function< auto()->int > f( foo );
 
may not necessarily compile with g++ -std=c++14 or Visual C++ 2015 or
later, then requiring an accommodate-the-silly-compiler rewrite like
 
using Int_func = auto() -> int;
std::function< Int_func > f( foo );
 
and then one may feel that that's so absurd & verbose that one writes
 
std::function<int()> f( foo );
 
Cheers!,
 
- Alf
David Brown <david.brown@hesbynett.no>: Nov 11 10:19AM +0100

On 10/11/15 12:58, Alf P. Steinbach wrote:
> self-documented code initiative?
 
> It's doesn't look very clear to me, but then, TeX never did look clear
> to me! :)
 
One issue here is that TeX's paragraph algorithm is a great deal more
sophisticated than the simple one described in this problem. It covers
hyphenation, stretchable spaces (with different degrees of stretchiness
for different types of space - the space between letters has very little
stretchiness, while the the space after a period has lots), configurable
parameters, good/bad break hints, and so on.
Juha Nieminen <nospam@thanks.invalid>: Nov 11 09:35AM

> What an utter complicated mess. Even if C++ is not as good at string
> processing as, say, awk, perl or Tcl, I cannot believe that you need
> coroutines or threads (WTF? Mutexes???) for such a simple problem.
 
Clearly you haven't been programming enterprise solutions enough.
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Rosario19 <Ros@invalid.invalid>: Nov 11 08:20PM +0100

On Mon, 9 Nov 2015 15:57:41 +0100, "Alf P. Steinbach" wrote:
 
 
>All three solutions use the following support code, coded up for the
>exercise, which I KNOW has its problems, and may not even be correct.
 
>So ;-)
 
this is my try. i'm not so sicure it is right...
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
 
#define u32 unsigned
#define i32 int
#define u8 unsigned char
 
#define R return
#define P printf
#define F for
#define GG(a,b) if(a)goto b
#define G goto
 
int main(int c, char** a)
{u8 *buf;
u32 w, i, j, iWrd;
i32 k, r, v;
 
if( c>1&&a[1]&&isdigit((u8) a[1][0]) )
w=atoi(a[1]);
else w=80;
if(w<1||w>0xFFF0)
{P("Argument number out of range:\n");
l0: P("Usage: thisProg number <filein >fileout\n");
P("Usage: thisProg <filein >fileout\n Number=80\n");
l1: R 1; // wrong
}
buf=(u8*) malloc(w+8);
if(buf==0){P("Memory insufficient\n"); G l0;}
F(i=0, iWrd=0; ; )
{k=getchar();
if(k==-1||!(v=isalpha(k))) // EOF or ERROR or not alpha
{if(iWrd){//Svuota buffer word;
if( (iWrd+i)> w ) // aaaa==4
{P("\n"); i=0;}
F(j=0; j<iWrd; ++j)
{r=putchar(buf[j]); ++i;
GG(r==-1||i>w, l1);
}
iWrd=0;
}
}
GG(k==-1,l3); // exit ok
if(v){// scrivi nel buffer
buf[iWrd++]=(u8)k;
GG(iWrd>w, l1);
}
else {// scrivi nel output
if(i>=w)
{if(k!='\n') P("\n");
i=0;
}
// \13\10=\n conta 0
r=putchar(k);
if(k!=13) ++i; // il 13 non conta
if(k=='\n') i=0;

GG(r==-1, l1);
}
}
l3:
if(ferror(stdin)||ferror(stdout)) G l1;
else R 0; //ok
}
Rosario19 <Ros@invalid.invalid>: Nov 11 08:48PM +0100

On Wed, 11 Nov 2015 20:20:44 +0100, Rosario19 wrote:
 
> F(j=0; j<iWrd; ++j)
> {r=putchar(buf[j]); ++i;
> GG(r==-1||i>w, l1);
 
pheraps it is better r==EOF and not r==-1
but here i remember EOF is -1
Rosario19 <Ros@invalid.invalid>: Nov 11 09:20PM +0100

On Wed, 11 Nov 2015 20:48:58 +0100, Rosario19 wrote:
>> GG(r==-1||i>w, l1);
 
>pheraps it is better r==EOF and not r==-1
>but here i remember EOF is -1
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
 
#define u32 unsigned
#define i32 int
#define u8 unsigned char
 
#define R return
#define P printf
#define F for
#define GG(a,b) if(a)goto b
#define G goto
 
int main(int c, char** a)
{u8 *buf=0;
u32 w, i, j, iWrd;
i32 k, r, v;
 
if( c>1&&a[1]&&isdigit((u8) a[1][0]) )
w=atoi(a[1]);
else w=80;
if(w<1||w>0xFFF0)
{P("Argument number out of range:\n");
l0: P("Usage: thisProg number <filein >fileout\n");
P("Usage: thisProg <filein >fileout\n Number=80\n");
l1: free(buf);
R 1; // wrong
}
buf=(u8*) malloc(w+8);
if(buf==0){P("Memory insufficient\n"); G l0;}
F(i=0, iWrd=0; ; )
{k=getchar();
if(k==EOF||!(v=isalpha(k))) // EOF or ERROR or not alpha
{if(iWrd){//Svuota buffer word;
if( (iWrd+i)> w ) // aaaa==4
{P("\n"); i=0;}
F(j=0; j<iWrd; ++j)
{r=putchar(buf[j]); ++i;
GG(r==EOF||i>w, l1);
}
iWrd=0;
}
}
GG(k==EOF,l3); // exit ok
if(v){// scrivi nel buffer
buf[iWrd++]=(u8)k;
GG(iWrd>w, l1);
}
else {// scrivi nel output
if(i>=w)
{if(k!='\n') P("\n");
i=0;
}
// \13\10=\n conta 0
r=putchar(k);
if(k!=13) ++i; // il 13 non conta
if(k=='\n') i=0;

GG(r==EOF, l1);
}
}
l3:
GG( ferror(stdin)||ferror(stdout), l1);
free(buf);
R 0; //ok
}
Rosario19 <Ros@invalid.invalid>: Nov 11 09:22PM +0100

On Wed, 11 Nov 2015 21:20:22 +0100, Rosario19 wrote:
 
>#define GG(a,b) if(a)goto b
>#define G goto
 
only one macro for goto is not sufficient...
Rosario19 <Ros@invalid.invalid>: Nov 11 09:59PM +0100

On Wed, 11 Nov 2015 21:22:35 +0100, Rosario19 wrote:
 
 
>>#define GG(a,b) if(a)goto b
>>#define G goto
 
>only one macro for goto is not sufficient...
 
your programs are all
+ wrong than my
because variable in input have not a limit...
 
for example "w" in a computer with finite resource
can not to be in a range 1..+oo
Christian Gollwitzer <auriocus@gmx.de>: Nov 11 10:54PM +0100

Am 10.11.15 um 22:59 schrieb Alf P. Steinbach:
 
>> What an utter complicated mess.
 
> It would be nice if you could supply some of your reasons for landing on
> this conclusion.
 
I am sorry for badmouthing your solution, which is perfectly fine (I
asssume; didn't have the motivation to work through it in detail). Only
that it solves a different task, that was not apparent to me from the
problem description. I can see lots of applications for pipelines in
programming. After looking up the telegram problem, I could understand
why you would solve it using your own implementation of pipes. This is
the problem with homework-style problems: there is often a much simpler
solution, which leaves aside the task which the problem is meant to
demonstrate. Implemening pipes in a langugage with coroutines is indeed
a very simple thing, in fact Python uses generators for almost all for
loops today. Ignoring the "use pipes" requirement, I am still failing to
see how this is surprisingly difficult.
 
I am not even convinced that the streaming is part of the specification.
Loading all of the file into memory and working from there, which leaves
aside all the buffering issues, would also be a correct solution,
wouldn't it?
 
> characters designated as whitespace. I don't know how well the standard
> library supports that, but it can't support it with SBCS encoding.
 
> Or, one may simply roll that problem up in one's definition of "word". ;-)
 
That applies to your code also: you use operator >> to tokenize the
input. AFAIK there is no way to influence operator >> how it should
treat whitespace. In unicode this is a non-trivial problem, since there
exist non-breaking spaces and spaces with zero-width, direction-changer
and similar complicated stuff.
 
> For an empty input this code outputs a blank line, but also that's
> ultimately a matter of specification.
 
Correct. This is underspecified.
 
> Also it has a hardcoded max line length instead of the problem
> statement's "takes a number w", which is not a matter of specification,
> but is trivial to fix.
 
Yes, but your fix introduces many bugs.
 
> int const max = stoi( args[1] );
 
What happens if you pass negative number? What happens if you pass text?
What happens if you pass more than two arguments or no argument?
In the latter case I think you are lucky that the code does not invoke
UB. argv[argc] contains a single NULL byte, i.e. an empty string IIRC.
 
 
> I didn't cover that angle because it was not so interesting for what I
> was investigating.
 
> But I think the following is shorter, while clear, don't you agree?
 
This code is almost the same as mine;
 
 
> auto main( int, char** args ) -> int
> {
> int const max = stoi( args[1] );
see above
> wstring word, separator, line;
separator is not used, is it?
> line.clear();
> }
> line += (line.length()? L" " : L"") + word;
 
I don't like treating integers as boolean values; I would rather write
line.length() > 0, assuming that you did not do that just for brevity?
 
> wcout << line << endl;
> }
 
> In case you'd think there a missing "return": nope.
 
I don't understand why you can leave it off; again I hope you haven't
the false impression that I was code-golfing. I believe that this
solution, at least to the problem as stated, is easier to understand
than any of your pipeline versions.
 
Christian
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 11 09:08PM

Some of the idiotic things that regulars of this newsgroup advocate:
 
1) Don't use the unsigned integral types despite the fact that the C++
standard library is full of their use.
2) Don't use abstract interfaces (as they advocate against using public
virtual functions).
3) Never derive from standard containers despite the fact that interface
augmentation is useful.
4) Don't use reference members despite the fact that not all classes
need to
be Assignable.
5) Use the memory allocated by std::vector<POD>::reserve() without
constructing elements by bypassing std::vector's modification functions
(e.g. push_back).
 
Use this newsgroup with caution.
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 11 10:47PM +0100

On 11/11/2015 10:08 PM, Mr Flibble wrote:
> 5) Use the memory allocated by std::vector<POD>::reserve() without
> constructing elements by bypassing std::vector's modification functions
> (e.g. push_back).
 
For once you write something sensible, Leigh, and I agree with you, so far.
 
The above are absolutes and absolutes are plain stupid in themselves. If
programming could be reduced to simple absolute mechanical rules, then
the robots would be doing most of it now. They're not.
 
Regarding (1), when it's suitably qualified, you know we disagree. I
advocate using unsigned integral types for bit-fiddling, while you, at
least that's my impression of old, advocate using them wherever an
integral value can't or shouldn't be negative. I advocate just using
properly named signed type for that.
 
Regarding (2) I find it difficult to think of any qualification that
would make it not-stupid. But it may exist. My failure to think of a
suitable qualification could be due to not recognizing the relevant
situations as manifestations of the problems this rule is meant to avoid.
 
Regarding (3), some standard containers have protected members. That
means that they're designed to be derived from. These standard
containers do not have virtual destructors, so they're not designed for
polymorphic destruction. But in short, the advice boils down to not
deriving from classes designed to derive from. That's dumb.
 
Regarding (4), that's just very perplexing.
 
Regarding (5), ditto: are you sure that's what was advocated?
 
 
Cheers,
 
- Alf
JiiPee <no@notvalid.com>: Nov 11 06:39PM

I sometimes see that error codes are coded like:
 
#define ERROR_IN_INPUT 1
#define TOO_LONG_INPUT 2
#define PARAMETER_ERROR 3
 
I was taught that const int is better than define, so why is it not:
 
const int ERROR_IN_INPUT = 1;
const int TOO_LONG_INPUT = 2;
const int PARAMETER_ERROR = 3;
 
?
is there some/any benefit for using define here? I thought that was
C-programming...
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 11 07:51PM +0100

On 11/11/2015 7:39 PM, JiiPee wrote:
 
> ?
> is there some/any benefit for using define here? I thought that was
> C-programming...
 
It may be that these id's are used in sources other than C or C++ source
code, and/or by tools other than C or C++ compilers.
 
For example, although it doesn't relate so well to error codes, the
Windows RC resource definition language depends on preprocessing via the
C preprocessor, which simplifes the task of connecting resource
definitions to C and C++ code. One can simply include a common suitably
restricted header in both an RC file and C and C++ souce code files.
 
And Windows API symbolic error code names are processed by the Message
Compiler, mc.exe. Essentially it produces a message resource that can be
embedded in a DLL, and accessed via the FormatMessage API function, e.g.
via Microsoft's errlook utility, or via PowerShell.
 
Of course the reason for the error codes you see could be anything really.
 
It could be sheer force of habit, perhaps strongly influenced by seeing
(but not understanding) this convention used for e.g. Windows error codes.
 
 
Cheers & hth.,
 
- Alf
JiiPee <no@notvalid.com>: Nov 11 07:29PM

On 11/11/2015 18:51, Alf P. Steinbach wrote:
 
> It may be that these id's are used in sources other than C or C++
> source code, and/or by tools other than C or C++ compilers.
 
Ok, so its some compilation issue. But if there is currently no usage
other than using it in the same program then maybe could do them as
const int. If later on other programs do need them then they can easily
be chenged to #define s.
legalize+jeeves@mail.xmission.com (Richard): Nov 11 09:31PM

[Please do not mail me a copy of your followup]
 
no@notvalid.com spake the secret code
 
>const int ERROR_IN_INPUT = 1;
>const int TOO_LONG_INPUT = 2;
>const int PARAMETER_ERROR = 3;
 
Prefer constants (as you have done) or enums over #define for C++ code
bases.
--
"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>
JiiPee <no@notvalid.com>: Nov 11 09:38PM

On 11/11/2015 21:31, Richard wrote:
>> const int PARAMETER_ERROR = 3;
> Prefer constants (as you have done) or enums over #define for C++ code
> bases.
 
ye I do, but I just see that some people use defines...
jacobnavia <jacob@jacob.remcomp.fr>: Nov 11 09:34PM +0100

Consider this file
 
int FRA = 1;
 
And this other file:
 
#include <cstdio>
extern const int FRA;
int main(void)
{
printf("FOO=%d\n", FRA);
}
 
OUTPUT:
 
1
 
Now, if I change the first file like this:
 
const int FRA = 1;
 
~/tmp $ g++ c.cpp d.cpp
Undefined symbols for architecture x86_64:
"_FRA", referenced from:
_main in d-6da259.o
ld: symbol(s) not found for architecture x86_64
 
Note that when the "const" is absent, the declaration in the second file
(the one with the main function) does NOT correspond to the declaration
of the first file.
 
Only if I define the integer as mutable (not const) the link works.
 
?????????????
 
Thanks for your time.
 
jacob
Bo Persson <bop@gmb.dk>: Nov 11 10:01PM +0100

On 2015-11-11 21:34, jacobnavia wrote:
> (the one with the main function) does NOT correspond to the declaration
> of the first file.
 
> Only if I define the integer as mutable (not const) the link works.
 
You should have the "extern" in a header, and include that in both
source files. Otherwise using const implies static.
 
Another C++ feature.
 
 
 
Bo Persson
jacobnavia <jacob@jacob.remcomp.fr>: Nov 11 10:05PM +0100

Le 11/11/2015 22:01, Bo Persson a écrit :
> using const implies static
 
!!!!!!!
 
WOW I didn't expect that. Thanks
Paavo Helde <myfirstname@osa.pri.ee>: Nov 11 03:08PM -0600

jacobnavia <jacob@jacob.remcomp.fr> wrote in news:n208kr$tmo$1@dont-
email.me:
 
 
> 1
 
> Now, if I change the first file like this:
 
> const int FRA = 1;
 
'const' implies internal linking by default in C++ (unlike in C), so this
FRA is not visible in other files. You probably need (not tested):
 
extern const int FRA;
const int FRA = 1;
 
hth
Paavo
 
 
> _main in d-6da259.o
> ld: symbol(s) not found for architecture x86_64
 
> Note that when the "const" is absent, the declaration in the second
file
jacobnavia <jacob@jacob.remcomp.fr>: Nov 11 10:16PM +0100

Le 11/11/2015 22:08, Paavo Helde a écrit :
> extern const int FRA;
 
YES, that "fixes" it.
 
extern const int FRA = 1;
 
Ahhh c++...
 
Thanks for your help
Ian Collins <ian-news@hotmail.com>: Nov 12 10:24AM +1300

jacobnavia wrote:
>> using const implies static
 
> !!!!!!!
 
> WOW I didn't expect that. Thanks
 
It allows one to define a const value in a header, which in C would
result in multiple definitions.
 
--
Ian Collins
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: