- Inline functions, ODR, logging - 4 Updates
- Failed interview test - 7 Updates
- PNG Coding - 4 Updates
- "Use Stronger Types!" - 2 Updates
- Error in cplusplus.com atomics op= - 1 Update
- /usr/include/*.h - 4 Updates
- Failed interview test - 2 Updates
- ref use - 1 Update
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:
Post a Comment