Wednesday, November 16, 2016

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

scott@slp53.sl.home (Scott Lurndal): Nov 16 01:50PM


>> static inline void function(void) const
 
>The (void) above is a C-ism.
 
so what? It's both legal and expressive.
 
variable++ is also a C-ism.
David Brown <david.brown@hesbynett.no>: Nov 16 05:21PM +0100

On 16/11/16 08:27, Paavo Helde wrote:
>> std::cout << FOOBAR << std::endl;
>> }
 
> The (void) above is a C-ism.
 
Yes, and it is IMHO a good one. Making "void foo()" in C mean a
function with a variable or unspecified number of arguments was a
terrible idea. Changing it in C++ to mean no arguments was only a
little less bad - it should simply have been a syntax error. Then
people would have been forced to use the clear syntax of "void
foo(void)" that is consistent with C, and it would have avoided the
"most vexing parse" in C++.
 
> logging and asserts are often performed via function-style macros, one
> reason being to able to expand __LINE__ in the correct place, e.g.:
 
> #define LOGGER(msg) { Logger::Log(__FILE__, __LINE__, msg); }
 
Macros are not evil. Using macros when there are better solutions is
evil, and /abusing/ macros is evil.
 
Changing the meaning of an include file depending on the definition of a
macro is evil, and that is the root of the problem here.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 16 06:07PM +0100

On 16.11.2016 14:50, Scott Lurndal wrote:
 
>>> static inline void function(void) const
 
>> The (void) above is a C-ism.
 
> so what? It's both legal and expressive.
 
It doesn't express anything in C++.
 
 
 
> variable++ is also a C-ism.
 
No, that's the same in both languages.
 
 
Cheers & hth.,
 
- Alf
Andreas <nospam@invalid.invalid>: Nov 16 11:15PM +0100


> inline void Bogus::p(const char* arg) const {
> std::cout << arg << std::endl;
> }
 
Ah, that's interesting. But I do not want to require an additional
parameter for each inline function, because that parameter would have no
relationship with the responsibilities of the function.
 
> #define LOGGER(msg) { Logger::Log(__FILE__, __LINE__, msg); }
 
> hth
> Paavo
 
Yes, it does indeed, thanks. You made it clear to me that my posting
was misleading because I did not explain my point well enough.
 
Bogus::p was _not_ meant to replace a logger as your macro above, but as
an inline function using such macro. Like so:
 
inline void Bogus::p() const {
LOGGER("Bogus::p was called!");
}
 
As your LOGGER macro uses __FILE__, it will violate ODR when used in
Bogus::p in the same way that the use of FOOBAR will violate it. I'm
looking for a viable alternative for such a macro for use in inline
functions.
 
 
--
What do you mean? An African or a European swallow?
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Nov 16 03:11AM -0700

On Wed, 16 Nov 2016 09:23:55 +0100, "Alf P. Steinbach"
 
>On 16.11.2016 09:16, Louis Krupp wrote:
>> 0 <= d <= 1000
 
>Where did you see that? I l00ked for it.
 
From TestQuestions.txt:
 
================
Question 6
 
We define a redundant node in a singly-linked list to be a node whose
data value matches the data value of a previous node in the list. In
other words, given node node containing data value d , some node node
(where i < j) having data value d is redundant if d == d . For
example, given a zero-indexed linked list in the form list = {3, 4, 3,
2, 2}, the redundant nodes are located at indices 2 and 4.
 
Complete the optimal function in the editor below. It has one
parameter: a LinkedListNode, head , referencing the first node of a
singly-linked list. The function must return a LinkedListNode
referencing the first node of a list that contains only the
non-redundant nodes from the original list (and none of the redundant
ones). All non-redundant nodes must be in the same exact order as they
were in the original list.
 
Input Format
 
Locked stub code in the editor reads the following input from stdin
and passes it to the function:
 
The first line contains an integer, n, denoting the number of elements
in list. The second line contains n space-separated integers where
each integer i describes the data value of the i node in the list.
 
Constraints
 
Each list contains 10 nodes.
 
0 <= d <= 1000 <- Note that the file uses the left arrow character
 
Output Format
 
The function must return a LinkedListNode referencing the first node
of the optimized list. This is printed to stdout by locked stub code
in the editor.
 
Sample Input 0
83 <- I have no idea what this is.
4 3 2 6 1 2 6
 
Sample Output 0
34261
 
Explanation 0
Let's consider our list to be list = 3 -> 4 -> 3 -> 2 -> 6 -> 1 -> 2
-> 6, and refer to each node as list where 0 = i < n. We can make the
following statements:
 
* list = 3 is redundant to list = 3, because both nodes have matching
data values and list appears later in the list.
* list = 2 is redundant to list = 2, because both nodes have matching
data values and list appears later in the list.
* list = 6 is redundant to list = 6, because both nodes have matching
data values and list appears later in the list.
 
We then return a LinkedListNode referencing list = 3 -> 4 -> 2 -> 6 ->
1, which both preserves the initial ordering of all non-redundant
nodes and does not contain any redundant nodes.
 
For Reference:
 
/* LinkedListNode
* {
* int val;
* LinkedListNode* next;
* };
*
* LinkedListNode* optimal(LinkedListNode* head)
*/
================
 
Louis
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 16 01:04PM +0100

On 16.11.2016 11:11, Louis Krupp wrote:
 
> Constraints
 
> Each list contains 10 nodes.
 
> 0 <= d <= 1000 <- Note that the file uses the left arrow character
 
I see. They do not provide all the relevant information in the problem
statement. They tack some of it on later, perhaps not recognizing its
importance, or perhaps to trip up folks.
 
For 10 nodes big O performance doesn't matter.
 
Still, an array is easier to code up than traversing the list.
 
 
Cheers!,
 
- Alf
scott@slp53.sl.home (Scott Lurndal): Nov 16 01:46PM


>They seemed to be pretty damn standard questions. I can't imagine I got
>them wrong.
 
>Any feedback?
 
Problem #7 is a very simple grammar, suitable for a recursive descent
parser. You should only need to scan each input string once (and
for an invalid grammar, you'll likely bail early). All those calls to
find_first_of() are very inefficient.
"Christopher J. Pisz" <cpisz@austin.rr.com>: Nov 16 11:12AM -0600

On 11/16/2016 7:46 AM, Scott Lurndal wrote:
> parser. You should only need to scan each input string once (and
> for an invalid grammar, you'll likely bail early). All those calls to
> find_first_of() are very inefficient.
 
See bracesOptimized
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Nov 16 12:54PM -0700

On Tue, 15 Nov 2016 14:05:08 -0600, "Christopher J. Pisz"
 
>They seemed to be pretty damn standard questions. I can't imagine I got
>them wrong.
 
>Any feedback?
 
Here's a relatively simple solution to #7. You'd get hired on the
spot, or you'd get eliminated for being weird. Either way, they'd
remember you:
 
===========================
#include <stdio.h>
 
static bool bmatch(const char *s)
{
const int N = 100;
char open_code[N];
int level = 0;
int i;
char c;
 
for (i = 0; i < N; i++) open_code[i] = 0;
 
while ((c = *s++)) {
int code = 0;
switch (c) {
case '{':
code += 1;
/* fall through */
case '[':
code += 10;
/* fall through */
case '(':
code += 100;
if (level >= N) return false;
open_code[level] = code;
level++;
break;
case '}':
code += 1;
/* fall through */
case ']':
code += 10;
/* fall through */
case ')':
code += 100;
level--;
if (level < 0) return false;
if (open_code[level] != code) return false;
break;
default:
break;
}
}
 
return true;
}
 
static void test(const char *s)
{
printf(">%s< %s\n", s, bmatch(s) ? "yes" : "no");
}
 
int main()
{
test(" ");
test(" () ");
test(" [] ");
test(" {} ");
test(" {}} ");
test( " {}] ");
test(" { [ ( ) ] } ");
test(" ( [ ( ) ] } ");
test(" { ( ( ) ] } ");
test(" { [ ( ) . } ");
test(" { . ( ) ] } ");
test(" { [ ([) ] } ");
 
return 0;
}
===========================
 
(Yes, you'd probably want to replace printf with something a little
more modern.)
 
Louis
Christian Gollwitzer <auriocus@gmx.de>: Nov 16 09:19PM +0100

Am 16.11.16 um 20:54 schrieb Louis Krupp:
> case '(':
> code += 100;
> if (level >= N) return false;
 
Instead of the weird "code" thingy, if you would store the open brace in
the open_code array, then this seems like a reasonable algorithm.
Basically it implements a pushdown automaton to parse the neted braces.
 
In C++, one could use a vector<char> as the stack and eliminate the
arbitrary upper size limit
 
 
Christian
Daniel <danielaparker@gmail.com>: Nov 16 01:19PM -0800

On Tuesday, November 15, 2016 at 3:05:20 PM UTC-5, Christopher J. Pisz wrote:
> I've been taking some screening tests for interviews lately.
 
Ah, interview questions.
 
Back in 2000, the Toronto based startup that I was doing a contract assignment
with got bought up by an American company, and being bought up usually meant
the decimation of the startup, sooner or later. With not much to do, I
sent a resume to to a California agency, and got back a contract opportunity at
a San Francisco on-line trading company to assemble and lead a web development
team which was a joint development with a New York based wealth management
company that they had just acquired. So I found myself on the phone having an
interview with a VP from the on line trading company. The interview was going
fine, except I felt an air of unreality about it, as my background was C, C++
and Java development, not web. Towards the end of the interview, I ventured
that I didn't have a lot of experience in web development (by which I meant
that I didn't have any), and whether that was going to be a problem. The VP
replied that she wasn't technical, and she would leave it up to the technical
guy in New York to decide. Anyway, when I had the interview with the
guy in New York, the subject of web never came up, and I received an offer.
 
I did run this by a friend of mine before accepting, expressing my
reservations. He was reassuring. Web development was easy, he said, we'd been
doing really hard C++ work for years, but web was easy. Thus encouraged, I
accepted the offer.
 
So I went to San Francisco, and had to hire a team. This was during the dot com
boom, my boss in San Francisco told me that anyone we interviewed we wanted to
hire, they'd best get that call on their cell phone as they left the building,
otherwise they would already be taken. I really wanted to hire someone who knew
something about web development, since I didn't know anything.
 
Everybody I interviewed, all supplied through agencies, were recent arrivals
from India. The first guy, I started with a question about architecture. I
listened really carefully to the answer, did it make sense? not make sense? I
simply couldn't tell. Maybe, I thought, it's a language issue. I glanced at his
resume and saw five years of experience with Java and EJB's.
 
Okay, I said, how do you create a new Java object? Gosh, darn, that was a
difficult question, you could see it on his face. With the create statement, he
hazarded, with just a hint of a question mark at the end of it, a surreptitious
glance, trying to gauge my reaction. I tried to keep my face blank.
 
So the interviewing went, interviewing guys with obviously fabricated resumes.
Fabricated by the agencies, most likely. Until we got to a young woman recent
graduate from the Mother Theresa school in India, who didn't know much either,
but she was obviously smart, her eyes didn't glaze over when I asked her
questions, she followed up with questions of her own when she didn't know
something, and her resume more or less reflected her knowledge. So we hired
her. Then I interviewed a husband and wife in succession, the husband was
obviously faking it, the wife was good so we hired her.
 
The project was a success.
 
Daniel
https://github.com/danielaparker/jsoncons
Christian Gollwitzer <auriocus@gmx.de>: Nov 16 10:06AM +0100

Am 16.11.16 um 09:01 schrieb Juha Nieminen:
> (I don't think linkers will check if two static functions are
> completely identical in content and merge them. If some do, great,
> but AFAIK they usually don't.)
 
Well nothing stops you from removing the static declarations and
replacing it by either inline or turn the header file into a "real"
library. The license for all the libraries he lists at
https://github.com/nothings/single_file_libs is zlib, MIT or public
domain, i.e. basically "do whatever you want with it" - and for most
parts it is extremely impressive how they fit the functionality into
such a small numbero of LOCs with zero dependencies.
 
Partly the "static" seems to be motivated by the missing "inline" in
older C compilers.
 
You can also always wrap the functionality for you own use in your
larger project.
 
 
Christian
scott@slp53.sl.home (Scott Lurndal): Nov 16 01:44PM

>to excavate the problem myself. I'm not looking to create a huge
>library, just to look at the files at this point under the hood,
>perferably in a single file program
 
Then look for netpbm.
Wouter van Ooijen <wouter@voti.nl>: Nov 16 06:01PM +0100

Op 16-Nov-16 om 9:01 AM schreef Juha Nieminen:
> large static functions (because C doesn't support inline)? Come on.
> That goes a bit too far. If you ever include the header file in more
> than one place, you'll be duplicating all the code in your executable.
 
I don't see why that would lead to executable bloat. Did you try this?
 
Wouter "Objects? No Thanks!" van Ooijen
"Öö Tiib" <ootiib@hot.ee>: Nov 16 11:39AM -0800

On Wednesday, 16 November 2016 10:01:49 UTC+2, Juha Nieminen wrote:
 
> However, a header-only implementation using an enormous amount of very
> large static functions (because C doesn't support inline)?
 
AFAIK 'inline' is in C since C99 and I remember that several
C compilers supported it before 1999.
Tim Rentsch <txr@alumni.caltech.edu>: Nov 16 09:11AM -0800

> subtracted from 24 or to say that result of subtracting 42 from 24
> is -18. Those choices feel more common than to say that subtracting
> 42 from 24 is 0.
 
I'm only reporting what is common in mathematical texts
that discuss what used to be called "whole numbers" (and
which the ISO document now calls "natural numbers"). I
wasn't making any claim about which usage is "right",
only explaining my own usage.
 
>> always at least produce some number, which IMO makes them more
>> natural than the undefined behavior that happens with signed
>> types.
 
The domain of the natural numbers is infinite. The domains
of all standard integer types are bounded, not infinite.
 
Also, the domain of natural numbers does not include any
negative numbers. It seems odd to say that a signed
integer type, which does include negative numbers, is
more like the natural numbers than an unsigned integer
type, which does not include negative numbers.
 
> That "undefined behavior" is likely a result of sabotage.
 
I'm at a loss to understand what you mean here. The people
who wrote the original ANSI/ISO C standard surely were not
intending to cripple the behavior of arithmetic operations
for signed integer types. Presumably the behavior was left
undefined as a reflection of a wide variety of different
possible hardware platforms, both existing at the time and
plausibly existing in the foreseeable future.
 
> of signed integer overflow in definable manner and even the
> differences between behavior of different platforms could be
> indicated with a value of pre-defined macro or the like.
 
Sure, such a thing could be done, but that's not part of the
language. And as far as that goes, if what is wanted is
reliable operations for signed quantities, the easiest way
to do that is very likely to represent the signed quantities
with unsigned integer types.
Tim Rentsch <txr@alumni.caltech.edu>: Nov 16 09:32AM -0800

>> better choice than unsigned types is a significant overstatement.
 
> Unsigned types are good for bit-level stuff. In particular you don't
> want to do left-shifts with signed integers.
 
I agree with that.
 
> Signed integers are good for numbers, numerical values, when they're
> not mixed with signed integers.
 
I assume you meant unsigned at the end there. I agree here
also, depending on what kinds of numbers/numerical values
are involved.
 
> In particular you don't want implicit
> promotion of signed quantities to unsigned ones.
 
In some cases it works fine, in others not so much. I agree
that care and caution are called for.
 
> You don't want
> expressions like `string("blah").length() < -1` in your code.
 
Comparisons between signed types and unsigned types are
rightly viewed with suspicion, and often wrong. I can't
think of a case where the expression shown above is something
any sensible person would write.
 
> notions of size. This lack of standard library support -- not even in
> any in Boost, as far as I know -- makes it difficult for individual
> programmers to transition to non-risky types for each usage area.
 
That does sound rather troublesome. I'm not sure though that
just making everything signed is the best approach either.
"K. Frank" <kfrank29.c@gmail.com>: Nov 16 09:19AM -0800

Hello Group!
 
The standard states -- 29.6.5-32 -- that for a std::atomic
type, "C A::operator op=(M operand);"
 
Returns: fetch_key(operand) op operand
 
That is, the return value is, as one would expect, the
result of performing the operation.
 
(I am looking at the N3242 draft standard, pg. 1127.)
 
cplusplus.com has in their atomics reference section:
 
http://www.cplusplus.com/reference/atomic/atomic/operatororequal/
 
Each of this functions accesses the contained value, apply
the proper operator and return the value the contained value
had immediately before the operation
 
and
 
Return value
The contained value before the call.
 
So, they have it backwards (as if they were describing
post-increment, rather than pre-increment semantics).
 
 
Happy Hacking!
 
 
K. Frank
Christian Gollwitzer <auriocus@gmx.de>: Nov 16 11:05AM +0100

Am 16.11.16 um 04:29 schrieb Popping mad:
> or
> #include <czlib>
 
> to include it in my program. It is not being seen.
 
The compiler really only looks for the name that you put into the <>.
#include <cstdio> to include #include <stdio.h> in std) only works,
because the C++ library ships with file called "cstdio", which
basically does
 
namespace std {
#include <stdio.h>
}
 
There is no magic by which the compiler would derive the .h file from
the extensionless name.
 
Christia
Popping mad <rainbow@colition.gov>: Nov 16 10:23AM

On Wed, 16 Nov 2016 11:05:53 +0100, Christian Gollwitzer wrote:
 
> }
 
> There is no magic by which the compiler would derive the .h file from
> the extensionless name.
 
 
that also goes for including the .h which we, by convention do in C but
in C++ we drop the .h from the #includes?
Paavo Helde <myfirstname@osa.pri.ee>: Nov 16 01:12PM +0200

On 16.11.2016 12:23, Popping mad wrote:
>> the extensionless name.
 
> that also goes for including the .h which we, by convention do in C but
> in C++ we drop the .h from the #includes?
 
This is not a convention. It's just that C++ standard decided to define
some header files with no filename extension. IIRC the idea was that
these might not be real disk files at all, so a filename extension is
not needed. But in reality typical implementations still have them as
actual disk files.
David Brown <david.brown@hesbynett.no>: Nov 16 05:15PM +0100

On 16/11/16 12:12, Paavo Helde wrote:
> these might not be real disk files at all, so a filename extension is
> not needed. But in reality typical implementations still have them as
> actual disk files.
 
It has the convenience of making it easy to distinguish standard library
headers and other headers that might be on your compiler's include
paths, and means that the C++ standard library can add new headers
without worrying about conflicts.
ram@zedat.fu-berlin.de (Stefan Ram): Nov 16 11:36AM

>Locked stub code in the editor reads the following input from stdin
>and passes it to the function:
 
I can't read the stub in the post, but my draft looks
something like:
 
#include <initializer_list>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
#include <stdexcept>
#include <string>
 
struct LinkedListNode {};
 
static inline int getnum( ::std::stringstream s )
{ int num; s >> num; return num; }
 
static inline int getnext( ::std::stringstream & s )
{ int num; s >> num; return num; }
 
bool seen( int const number ){ /* todo */ return false; }
 
bool append
( LinkedListNode & list, LinkedListNode * * alast, int const number )
{ /* todo */ return true; }
 
void clear( LinkedListnode & list ){ /* todo */ }
 
bool cantadd(){ /* todo */ throw ::std::exception{}; }
 
LinkedListNode & distinct
( ::std::string const & firstline,
::std::string const & secondline )
{ int const n = getnum( ::std::stringstream { firstline } );
::std::stringstream s ( secondline );
static LinkedListNode list; LinkedListNode * last;
for( int i = 0; i < n; ++i )
{ int d = getnext( s );
if( !seen( d ))if( !append( list, &last, d ))
{ clear( list ); cantadd(); break; }}
/* todo: revise this code for exception-safety */
return list; }
 
They want a reference to be returned? I have little experience
with how to do this, so I used »static« for the time being,
which is ugly.
 
We are dealing with dynamic allocation here, so a unique_ptr
might be a better type for the result.
 
Some details are still left to do and are marked with »todo«
above.
ram@zedat.fu-berlin.de (Stefan Ram): Nov 16 11:59AM

>if( !seen( d ))if( !append( list, &last, d ))
 
This line is the heart of my algorithm.
 
But »seen« needs its own memory, and I want
to avoid static locals, so I'd make that a
functor.
Popping mad <rainbow@colition.gov>: Nov 16 10:38AM

I'm reading up on concurrency with the thread libraryis C++ Concurrency
in action by Anthony Williams and I'm puzzled by one example having to do
with sending references of objects through the threads. If you own the
text, it is one page 24 where he is callable functions is
 
void update_data_for_widget(widget_id w, widget_data& data);
 
the call for the thread is
 
std::thread t (update_data_for_widget, w, data); where data is an object,
of data I suppose ;)
 
to do this correctly he says we need to use ref and a reference wrapper
 
std::thread t(update_data_for_widget, w, std::ref(data) );
 
Why can't you just send a reference?
 
std::thread t(update_data_for_widget, w, &data );
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: