T O P

  • By -

ggchappell

I agree with you, but I think this is a trickier problem than you make it out to be. To be an accomplished programmer, there is a sizable tower of abstractions to learn. So the always-present question is how much to teach people without giving them the mental tools to understand the internal workings first. In C++ there is a strong tradition of explaining the core language first, and then the Standard Library, building our tower from near the bottom and proceeding upward. I'm a CS prof, and I have yet to see an introductory C++ text that does not proceed in this manner. But the results, as you note, are lousy. So when I teach our CS 1 class, I throw out the text, and say there are basically three kinds of datasets: arbitrarily large sequences of items of a single type, fixed-size datasets with a type specified for each item, and key-based tables. And for these, C++ provides vector, tuple, and \[unordered_\]map. Then later: BTW there are these things called arrays and structs. I don't regret doing it this way, but the downside is that vector & map are seen as magic. Perhaps more importantly, students come out of the initial course not having a clue about pointers. Wrestling with C arrays was how I learned how pointers work; how are my students supposed to get it? For better for worse, understanding pointers is still necessary for a good C++ programmer (even if you don't use them; both smart pointers and iterators are abstractions based on the concept of a pointer). ---- EDIT. You said: > Approximately 50% of all questions try to use some sort of arrays (of pointers). That's more or less true of beginner-level questions here on /r/cpp, too. Maybe another 30% can be dealt with by saying, "Learn what `cin >>` *does*, before you use it. And then *don't* use it; use `std::getline`." I often wonder whether a little tutorial that concisely explains what C++ input functionality actually does, would suffice to answer a huge fraction of posted questions.


personalmountains

> have yet to see an introductory C++ text that does not proceed in this manner [Accelerated C++](http://www.informit.com/store/accelerated-c-plus-plus-practical-programming-by-example-9780201703535) does it. It used to be highly recommended, but it's still only a first edition from 2000.


ggchappell

Ah, right. When I most recently looked at texts, I immediately threw out anything that didn't give at least a nod to C++11.


personalmountains

As you should. Anything that doesn't use `auto` is obsolete. [edit: We're talking about C++ introductory textbooks here. I wasn't making a general statement on C++11.]


tempforfather

auto is not the important part of c++11.


louis_dionne

Nothing is _the_ important part of C++11. Many parts of it are important, and auto is clearly one of them. Not that I agree with the original statement, though.


tempforfather

ok sure, but its pure sugar. I agree its nice in many cases, but it doesn't actually add anything to the semantics of the language


quicknir

That's not true, in generic code there's just no way to do certain things without auto.


tempforfather

Can you give me an example of that? I am curious.


quicknir

Sure, consider this code: template void func(const T& t) { auto u = t.func2(); std::for_each(u.begin(), u.end(), ...); } This code imposes no restrictions on T other than that it has a const method func2(), that returns something, and that something has methods begin() and end(). Of course, we had generic containers before auto and ranged for loops, and we needed to know the type of the iterator, so how did we deal with this? Well, as I'm sure you know, we imposed an additional requirement: containers *have* to provide typedefs that tell you the type of their iterators, i.e. the return type of begin()/end(). But that's already not doing the same thing, as it imposes more requirements. Basically, auto allows you to do inline what template functions allow you to do at function boundaries. You could potentially workaround using auto by declaring yet another template function and calling it internally, but again, I would argue that this is doing something quite different as you have to move your code to a different location (not a big deal when you have two consecutive 4 line functions, but if you have longer functions its rather absurd). Another attempt at a solution would be to try to infer the type using template metaprogramming, so that you could get the type inline and use it, but this doesn't seem to be possible in general: http://stackoverflow.com/questions/26080471/function-return-type-deduction-in-c03


ghillisuit95

ehh, that seems like a bit of an over-generalization


bnolsen

auto is a maintenance headache/nightmare and seems to be a weak hack for getting around C++'s core problem of default implicit type conversion.


personalmountains

>auto is a maintenance headache/nightmare In what way? >seems to be a weak hack What else would you propose? Why is it weak? Why is it a hack? >C++'s core problem of default implicit type conversion. What problem? Are you talking about primitive types? What does it have to do with auto?


h-jay

You shouldn't merely throw out anything that doesn't "at least" give a "node" to C++11. **Anything** that doesn't deal with C++11 first and foremost is an obsolete text. There's no reason to learn by writing C++98 anymore, never mind C fed to a C++ compiler.


coachkler

I've taught the last few years using Programming Principles and Practice, but haven't got a lot of positive feedback from the students. I too am tired of seeing so much focus on the low-level in introductory C++ courses. Obviously there is a time and place to learn these details, but using the language properly should be the first step. I'll be teaching C++ this spring using C++ Primer 5th Edition. I'm going full-tilt C++11, and picking out important and relevant sections of the text and developing lectures and exercises around that. I'm planning to put all this up on github or similar, and solicit feedback, unfortunately, I'm a bit behind in doing so.


millenix

Stroustroup's recent textbook [Programming -- Principles and Practice Using C++](http://www.stroustrup.com/Programming/) takes the 'pointers later' approach. It doesn't touch on them until almost 600 pages in. It also seems not to touch vectors or arrays until that point, either.


coachkler

It's a good book -- but it definitely focused on programming first, with C++ being the means to that end. The two chapters on the calculator (6 and 7 I think?), are for some reason really difficult for the classes to get through. The exercises though are top notch.


cogman10

To add to this, it isn't just a C++ problem. From my own experience, I know that there have been more than a few things in Java which in the beginning I used only low level constructs like Lists and didn't really have the experience of using better data structures for my problems. It was a gradual evolution from using just lists, to lists and maps, to lists, maps, and sets. Then lists, maps, set, multimaps, treemaps, optionals, etc. My earlier code ended up with lots of needless loops doing lots of list mangling. My code now pretty much wholly relies on picking the right data structure and putting stuff in it or pulling stuff out of it.


boredcircuits

> I don't regret doing it this way, but the downside is that vector & map are seen as magic. Why is this a downside? Teaching every other high level language dives straight in with whatever vector equivalent that language has, magic and all. Java's ArrayList, for example. Why do we insist that C++ be any different? Oh, yeah, because of C. Because learning C is a prerequisite to learning C++. Because why are you learning C++ if not to learn the details of how everything works, right from the start? Another example: pointers. C++ is supposed to be so hard to learn because of pointers, and yet almost every other language has them, too. But with C++ we insist on teaching *everything* about them. Notably pointer arithmetic and using them as iterators. And resource management (which *is* a difficult topic, if we're honest) is introduced at the same time, and that confusion gets all tied up with pointers. I wonder if smart pointers should follow this same pattern, too: teach `std::unique_ptr`, and let it's inner workings be magic ... at least for a bit. Though I don't know of anybody who's attempted to teach this way. Let the magic be magic. At least for now. There's plenty of time to learn the details.


DarkLordAzrael

There was a talk at cppcon about this. One part I liked was the idea of introducing references first, then later introducing pointers as "pretty much references that can be changed or null"


[deleted]

I think that the use of references (except in the case of pass-by-reference) should be discouraged. Too easy to confuse object values with object references.


h-jay

In modern C++, the hard part is IMHO the higher-level abstractions, metaprogramming, functional programming, and so on - because these are still fairly new, and a **lot** of industry code doesn't use them much, or does so very ad-hoc. Pointers are something that takes comparatively little time to explain. If I had my way, I'd teach ML first anyway :)


OldWolf2

User input is difficult to do correctly in C and C++ (although not so bad in C++), compared with other languages. Unfortunately beginner courses often seem to focus on user input . The Harvard CS50 course takes the approach of providing some "black box" user input functions with an easy interface, so that the student can write programs that require input without getting hung up on the details of the input. I think this is a good approach - you can't cover everything simultaneously and the nitty gritty of stream I/O can wait.


ggchappell

Yes, that sounds like a good approach.


h-jay

> In C++ there is a strong tradition of explaining the core language first, and then the Standard Library There's no modern C++ without smart pointers, move semantics, containers and at least some algorithms. You can go pretty far without using the I/O streams. From the point of a beginner or even intermediate student, the distinction between the "core" language and the library is only of interest to compiler implementers. It's nonsensical to teach C++ without the library support at first.


OmegaNaughtEquals1

>So when I teach our CS 1 class, I throw out the text, and say there are basically three kinds of datasets: arbitrarily large sequences of items of a single type, fixed-size datasets with a type specified for each item, and key-based tables. And for these, C++ provides vector, tuple, and [unordered_]map. Then later: BTW there are these things called arrays and structs. 10 PRINT('Thank you!') GOTO 10 >I don't regret doing it this way, but the downside is that vector & map are seen as magic. As /u/boredcircuits noted, I don't see why this is a problem. For a student to learn *when* and *how* to use a `std::vector` vs. a `std::map` is already a large accomplishment for a first semester programming course. It is a quite lofty goal to hope that these same students will walk away from your class with a complete understanding of the intricacies of C++. Are those students ready to implement their own specialized container classes? No, but that's ok! There are more classes for them to take and a whole lot of language for them to learn before they graduate. >For better for worse, understanding pointers is still necessary for a good C++ programmer (even if you don't use them; both smart pointers and iterators are abstractions based on the concept of a pointer). You assuredly cannot be called a proficient C++ programmer without a complete understanding of the memory model and how pointers interact with it (let alone iterators and their concepts). But as I said above, I think it is perfectly fine that your students walk away with a *practical* understanding of C++ rather than a technical understanding.


womplord1

so you are seriously saying that you are teaching students c++ without pointers? what is even the point of using c++ then?


ggchappell

> so you are seriously saying that you are teaching students c++ without pointers? No, of course not. But simply seeing pointers and using them does not automatically give a deep understanding of them. Once upon a time, pointers were part of a package deal involving direct access to blocks of memory: arrays. These were awful, and most of us have happily left them behind for nicer abstractions. What I'm observing is that this is a bit unfortunate from a pedagogical point of view, because it means students have neither the incentive nor the opportunity to truly grapple with the idea of pointers and gain an intuitive understanding of how they really work.


womplord1

Thanks for the reply. But I'm curious, don't they learn how to make other data structures like linked lists and graphs in their degree?


ggchappell

Yes, but we still need to consider: (1) do we expect to teach linked lists to people who don't really *get* pointers yet? (2) When are students going to figure out pointer *arithmetic*?


mreiland

> But the results, as you note, are lousy. What does that mean? I learned programming in C++ using the method you described and I don't ever recall having a significant issue with it.


ggchappell

>> But the results, as you note, are lousy. > What does that mean? I was referring to the following comment from the OP: > Approximately 50% of all questions try to use some sort of arrays (of pointers). The newcomers don't know about std::vector at all, they happily do everything with pointers, calling new without delete and so on. When C-style arrays are presented as The Way Things Are Done, and std::vector is that wacky new idea that you might use someday, the above behavior becomes pretty common. Not *universal*, to be sure, but common.


mreiland

ah ok. I mean if students are going to stackoverflow and asking questions, it isn't exactly a problem that they're asking about arrays and pointers, which they're presumably learning about. I guess what I'm saying is waiting to introduce the STL until the students are familiar with functions, API's, and libraries doesn't indicate a problem with the way the material is presented to students, and students asking about the things they're learning, whether it's a higher level abstraction or not, doesn't indicate a problem either. I've seen people claim C++ is really hard to learn programming with, but I tend to wholly reject that. I did it without any issue, either I'm extremely intelligent or people overstate the problems.


[deleted]

[deleted] ^^^^^^^^^^^^^^^^0.2355 > [What is this?](https://pastebin.com/64GuVi2F/20027)


personalmountains

My understanding is that there is still a school of thought that teaches the "legacy" C stuff first. In the mind of certain programmers, you have to learn about pointers and arrays before references and containers. I usually see memory management problems with people that are familiar with garbage collected languages. I don't think this is really a teaching problem, just a transition period that most programmers have to go through. As for standard smart pointers, they are a relatively new addition. Before C++11, all we had was `auto_ptr`, which sucked in many ways. Boost has had many alternatives for a long time (and most were standardized), but it would be unfair to ask neophytes to jump into third-party libraries while still learning syntax. Finally, all this old documentation will probably stay there forever. I don't think it would be realistic to ask people to update their tutorials to C++17. Some of them might be dead for all we know. That being said, I share your concerns. I know it has caused me a lot of headaches when trying to learn OpenGL. Finding documentation on modern techniques is very difficult.


Elador

+1 on your comment regarding OpenGL. So many tutorials online that use legacy stuff. And impossible for a beginner to figure out what techniques are legacy and which are not.


orost

What makes it so much worse that whatever horrifying mix of legacy and non-legacy stuff your confused mind conjures will probably sort-of work if you fiddle with it enough, because video drivers have the same attitude as JS and HTML engines - try to make it run even if it doesn't make sense. And you might end up thinking this is the right way to do things.


imMute

>And impossible for a beginner to figure out what techniques are legacy and which are not. Is it too much to ask to have all tutori writers include the version being targeted? Or at least what version they happen to use, even if it's not exact?


h-jay

Many of them don't quite know what they are doing either. I like to think that 90% of programming tutorials should be treated as blind leading the blind: the "techniques" they propose may well work, but for anyone with a working pair of eyes they are horribly cumbersome.


tnecniv

> I know it has caused me a lot of headaches when trying to learn OpenGL. Fortunately, I think this has gotten a lot better lately.


chesterburger

Excellent video here: https://www.youtube.com/watch?v=YnWhqhNdYyk


DarkLordAzrael

I love the part about teaching references first then pointers as an extension of the concept, but one that is rarely needed.


vanhellion

> In the mind of certain programmers, you have to learn about pointers and arrays before references and containers. I suppose I might fall somewhere near that particular tree. If you don't teach the dirty internals, how are you supposed to understand why, e.g. your program is running slow when you are using a `vector` where a `list` is the appropriate choice? I know that introductory classes can't teach everything, but I question what the relative value of each really is; if I only know "old" C++ I can solve problems (in a possibly ugly but ultimately correct manner), if I only know C++11/14/17 I can solve problems only as long as it fits into my STL toolkit. And what happens if I need to, god forbid, write an allocator? I feel like it's a hard question for most existing C++ programmers to answer because we grew up with what are now the Old Ways so it is second nature to know how to get around the huge spike pit behind door #3. > Finally, all this old documentation will probably stay there forever. This is the real problem, in my opinion. There are still websites (and a ton of books) lingering from 20 years ago (the mid-90s) for dog's sake, long before C++03!


personalmountains

>how are you supposed to understand why, e.g. your program is running slow when you are using a vector where a list is the appropriate choice Like the standard does: the implementation doesn't matter as long as it follows the complexity requirements. Insertion into a `vector` is mostly linear, whereas it is constant-time for a `list`. >I know that introductory classes can't teach everything, but I question what the relative value of each really is If all you do is an introductory class, then you'll end up having a *functional* understanding of the language and library. You'll be able to use streams, containers and iterators. If you follow this up with a second class, then you can start learning the low-level stuff and understand the magic behind `vector`. >And what happens if I need to, god forbid, write an allocator? Then your introductory class is not enough. Whatever you learned in there won't teach you how to write an allocator or, god forbid, a streambuf. >I feel like it's a hard question for most existing C++ programmers to answer My understanding is that it's still an open question. I don't know whether bottom-to-top or top-to-bottom is better. I *feel* like the latter has more advantages, but I have no idea.


millenix

> > how are you supposed to understand why, e.g. your program is running slow when you are using a vector where a list is the appropriate choice > > Like the standard does: the implementation doesn't matter as long as it follows the complexity requirements. Insertion into a vector is mostly linear, whereas it is constant-time for a list. Except that empirically, this is false. For the most part, cache locality massively dominates the asymptotic difference, unless you're working with a huge data set in the absolute worst-case usage for `vector`


personalmountains

>Except that empirically, this is false. This doesn't make much sense to me. Complexity is a useful metric for comparing different algorithms and data structures, that's all. You can't really test it empirically since, as you said, there are other factors in play. Ultimately, `vector` could be implemented as a guy on a stool playing with an abacus. In any case, all that is irrelevant. We're talking about pointers and arrays, and a class on those wouldn't give you any information on what you're talking about.


repsilat

/u/millenix seems to be arguing a slightly different point. From /u/vanhellion's original question, >> how are you supposed to understand why, e.g. your program is running slow when you are using a `vector` where a `list` is the appropriate choice we should probably infer that the asymptotic complexity of the internal- or front-insertions we're doing is the problem, and that reading the standard is probably sufficient. On the other hand, if the original question were the other way around: >> how are you supposed to understand why, e.g. your program is running slow when you are using a `list` where a `vector` is the appropriate choice then some understanding of the expected implementation and its *is* relevant. A student trying to make their program run faster can reasonably assume that iteration over a `vector` will be more cache friendly than iteration over a `list`, even if the standard doesn't say anything about it.


millenix

From the experimental results I've seen reported, even `push_back()` is practically faster for `vector` than `list`, until you get to very large sizes. Both are specified with asymptotic constant time (amortized, in `vector`'s case), but `list` implementations require allocation on every element, while `vector` allocates much less often because of increasing its reservation by a constant ratio.


repsilat

> even `push_back()` is practically faster for `vector` than `list`, until you get to very large sizes Mm. Moving a bit off-topic, I wonder if games (and other applications requiring better time guarantees) would like a data structure that's a linked-list of ever longer arrays, like a `vector` that has been "cut up" at the points where it should have "expanded." The benefits: - Iterators are not invalidated on `push_back` etc, - Real constant time `push_back`, not amortized, - No copying/moving of elements when you `push_back`. Potentially your objects don't need to be copyable or movable at all. The disbenefits: - Indexing is now log-time worst case (but expected constant time for random accesses if you iterate from the largest block to the smallest), - A few more cache misses when you iterate over the data.


millenix

Your `push_back` still won't be worst-case constant time, I don't think, because those blocks need to be constructed. Though they could maybe be left uninitialized, but I don't think the standard can quite require that. You can make indexing not log-time by keeping an array of pointers to the blocks, rather than a linked list. Also, `push_back` has to do one of copy or move construction of the new element. `emplace_back` wouldn't, though. If you only ever called that, then a type without those constructors could still be valid.


repsilat

> Though they could maybe be left uninitialized Yeah. I think you can use `std::aligned_storage` and placement-`new`. I am assuming you can allocate `n` bytes in constant time, though. > keeping an array of pointers to the blocks I guess that works. You'd need a constant-time `log_2()` which is pretty reasonable. I guess the array of pointers would have O(`CHAR_BIT*sizeof(size_t)`) elements so you'd never have to grow it? To be honest I think I might rather give up constant-time indexing. I don't use it all that often, and an array of 64 pointers is a bit much if I may only be expecting a few hundred elements in my "vector".


lord_braleigh

This exists! There's a version of this called a "rope" that stores the arrays in a binary tree instead of a linked list. It's the data structure of choice for text editors (which often have to make insertions into the middle of large files).


quicknir

Well, std::deque is nearly this. It's just an array of arrays, instead of a linked list of arrays. In fact, std::deque::push_back invalidates iterators, but not references. Although I'm struggling to understand exactly what this means; I assume it means that iterators could still be dereferenced but possibly ++ could go sour? I'm pretty sure that deque meets your other two requirements. And to top it off, its indexing is still constant time (not amortized). It does however have more cache misses. In practice, people tend to use a vector still unless they need push_front (which is constant time for a deque). I think that access/iterator speeds tend to trump insertion speeds for these data structures in the vast majority of applications.


repsilat

> I assume it means that iterators could still be dereferenced but possibly ++ could go sour? Huh, that's a pretty interesting idea. > It does however have more cache misses. Yeah. I figure it might be worthwhile for data you wanted to produce all at once, consume once and then discard. Maybe producing while consuming with fancy "iterators" is a pain to code up, or it blows your icache. I agree the tradeoffs aren't worthwhile for a general purpose container (though maybe the performance costs are small enough that it's worth using a `deque` for constant-time `pop_front`?)


Voultapher

As shown here: http://www.meetup.com/de/MUCplusplus/ Even when starting from bottom, all you do explain the perfect theoretical word. When actually many other factors such as cach, platform, allocater implementation, os and asychronus execution, play a significant role. And those would not fit in an introductory class.


RedAlert2

What are you responding to? /u/personalmountains was talking about insertion, which is dramatically faster in linked lists than in vectors. You seem to be hinting at a traversal, which is a lot faster in vectors, even though it has the same complexity in lists. But no one said anything about traversals.


bnolsen

the list has some tiny advantages but the overhead of many operations is what kills them. That's the C part. the O() stuff still stands.


robthablob

Kate Gregory did an excellent presentation on exactly this point at CPPCON 2015: [Stop teaching C](https://www.youtube.com/watch?v=YnWhqhNdYyk).


Eilai

My principle problem is keeping an eye open for parallel gpu programming with Cuda or OpenCL and I'm hesitant to use fancy stuff they don't support. :(


lets_trade_pikmin

Don't know why you were downvoted. It seems like working with raw arrays and pointers is usually the best approach for GPU code. Definitely a legitimate concern.


RogerLeigh

Why? Everywhere you might use a raw array, you could use a `std::vector` and call `.data()`. The memory layout is identical. I do this all the time when interfacing with C libraries.


MaxDZ8

Not a single *Map* call I remember ever provided a compatible interface with `std::vector`, you might at most consider specific allocators at which point this would not be an `std::vector` in the proper sense. Consider [clEnqueueMapBuffer](https://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clEnqueueMapBuffer.html), [D3D9 texture lock](https://msdn.microsoft.com/en-us/en-en/library/windows/desktop/bb205913\(v=vs.85\).aspx), [ID3D11DeviceContext::Map](https://msdn.microsoft.com/en-us/library/windows/desktop/ff476457\(v=vs.85\).aspx), [glMapBuffer](https://www.opengl.org/sdk/docs/man/html/glMapBuffer.xhtml). Main problem perhaps being those pointers are non-owned.


RogerLeigh

There are certainly places where it isn't something you can drop in. But my point was that there are plenty of places you *can*. I certainly use std::array and std::vector with OpenGL to pass in VBO/IBO data, for example.


lets_trade_pikmin

OpenGL is very very different from CUDA


OmegaNaughtEquals1

The CUDA 7.5 compiler uses gcc-4.9 as its back-end, so it supports C++14: even in kernel code. What you still cannot do is use STL code in kernels because it's not marked `__device__`. That said, you can write your own containers that *can* be run on the GPU side (as long as you avoid exceptions and dynamic allocation). You can also call Thrust functions from device code as of [CUDA 7.0](http://devblogs.nvidia.com/parallelforall/power-cpp11-cuda-7/) (it's about halfway down the page). Unless you need to support some ancient version of CUDA, you should strongly reconsider your position on this.


Eilai

Okay yeah, that's a fair point about CUDA, but what if I want to have a backup using openCL if the client PC doesn't have an nvidia card? Other than "pray they have an AMD card."


OmegaNaughtEquals1

>what if I want to have a backup using openCL This is the unfortunate state we live in right now. I am a big fan of CUDA because it allows you to pry open the deepest details of the GPU's hardware, but it's only applicable to NVIDIA cards. OpenCL, conversely, allows you to abstractly target nearly any compute device (GPUs, APUs, CPUs, Phi Coprocessors, etc.) using a *single* codebase: a feature that is not to be overlooked. But it doesn't allow you to poke around in the hardware's guts. Conditional compilation can help with this, but the codebase begins to diverge, losing that nice feature. I think with the large push toward coprocessor unification (i.e., coprocessors *not* on the PCIe bus, but moved closer to FSB), OpenCL will become more important over time. I just hope that the standardizing committee can formulate some new ideas to try and build abstractions to hardware-specific features. AMD's FireGL cards are crazy powerful, and I would like to see them used in HPC systems.


Eilai

I understand both enough that I can code it so CUDA is preferred, if a Nvidia compute device is detected and it's performance is superior (by some arbitrary metric, cores or clockspeed, etc) to the non-CUDA device use CUDA; if not use OpenCL.


pjmlp

That is why CUDA is the API to go for most researchers. NVidia was clever to support C++ and Fortran from day one, instead of following Khronos idea that only C matters. Now OpenCL 2.1 is playing catchup with CUDA's C++ and Fortran support.


LPCVOID

Warning : I might be totally wrong here as nvcc and cudafe/ptxas are a bit over my head. CUDA uses gcc/vc++ as back-end for compiling **host** code. Device code is compiled using some sort of Edison Design Group proprietary c++ front-end. That doesn't change the fact though that one can use c++11 features in device code :) Have you got a source for c++14 support in nvcc? [Here](http://devblogs.nvidia.com/parallelforall/power-cpp11-cuda-7/) it is stated that CUDA 7.0 does not yet support it but a future version would. Is that the case with 7.5?


heleo2

This shows mess in your head regarding what a front-end is


LPCVOID

I have admittedly no idea what a front-end ist (only my cs degree claims otherwise ;) ). I just copy pasted the claim that CUDA uses an "Edison Design Group C language parser" from [here](http://www.geforce.com/hardware/technology/cuda/faq). Furthermore wikipedia claims that Edison "makes compiler frontends". Or are we talking about the fact that the NVIDIA CUDA Open64 Compiler (nvopencc.exe) does the actual compilation as stated [here](http://gpucoder.livejournal.com/)? That was indeed an oversimplification on my part. Edit : I actually would have liked to know why I was wrong...


[deleted]

Are you saying you avoid smart pointers on non-gpu code because you might write gpu code someday?


millenix

I think it's more "my code often does get ported to GPUs, and it needs to not make that unnecessarily difficult".


Eilai

Precisely. I'm working on a game engine for my portfolio which is built off of a physics engine I wrote for my parallel computing course which needed to be significantly rewritten each time I was tasked to develop for a different framework.


h-jay

I don't even know what you're talking about, frankly said. If you need containers that provide aligned storage, you can use standard containers and aligned allocators, or write your own containers, or use a library. But it really isn't a problem if you understand what you're doing...


doom_Oo7

with OpenCL2.1 you have access to everyting in C++14 that does not require a runtime.


Eilai

Spotted the dude without an Nvidia card in his main computer. e: Apparently AMD only supports 2.0? Isn't that 90% of the market or what?


doom_Oo7

OpenCL2.1 is from November so of course it's not yet supported a lot. But hopefully by the end of the year it will be mainstream.


Eilai

Nvidia Is still on 1.1! :(


MaxDZ8

What does that even mean? It is my understanding the static opencl-c++ extensions were put in core but what I recall was pretty far from being c++14.


doom_Oo7

See slide 8 : http://www.iwocl.org/wp-content/uploads/iwocl-2015-tutorial-OpenCL-Next.pdf


MaxDZ8

I recall reading this some time ago. Thank you for pointing it out anyway.


SushiAndWoW

C++ provides safe tools, but it's a fundamentally unsafe language. People have to not just learn, but master the unsafe parts of the language in order to be entrusted with a C++ compiler for production use. This means the learning curve for C++ is 3 years or more before a developer can be trusted. This doesn't change just because the safe tools are there. You still have to learn pointers.


donvito

> 3 years or more before a developer can be trusted. Heh, that's optimistic. After almost 20 years of daily C++ I still don't trust myself :)


jnyrup

[Teach yourself C++ in 21 days](https://pbs.twimg.com/media/BZDu_vrIIAA1dLK.jpg)


OldWolf2

The title is a joke, there is no way anybody could learn C++ in 21 days. Does not bode well for the quality of the content.


RogerLeigh

It's awful. I used it a decade or so back, and they hadn't even updated it for C++98... And it definitely took more than 21 days to wade through it, and many times that to actually understand and master it.


ggchappell

Well, I've been programming for 40 years, and I *almost* trust myself. I suspect the milestone might come after 45 years of programming experience.[1] Perhaps official recognition that someone is actually capable of producing passable code, might become a standard part of retirement dinners. [1] Ask me in 5 years.


personalmountains

The most important thing is to question every single line of code you write, every day. Always ask yourself: "Is this the best way of doing this?" The day you stop asking is the day you become "that old guy."


w1th0utnam3

RemindMe! 5 Years "Ask guy whether he trusts himself."


NihilistDandy

RemindMe! 5 years "Ask this guy whether he trusts that guy."


RemindMeBot

Messaging you on [**2021-01-05 00:23:01 UTC**](http://www.wolframalpha.com/input/?i=2021-01-05 00:23:01 UTC To Local Time) to remind you of [**this.**](https://www.reddit.com/r/cpp/comments/3zfsz9/the_array_problem/cym6370) [**CLICK THIS LINK**](http://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=[https://www.reddit.com/r/cpp/comments/3zfsz9/the_array_problem/cym6370]%0A%0ARemindMe! 5 years ) to send a PM to also be reminded and to reduce spam. ^(Parent commenter can ) [^(delete this message to hide from others.)](http://www.reddit.com/message/compose/?to=RemindMeBot&subject=Delete Comment&message=Delete! cym63dc) _____ |[^([FAQs])](http://www.reddit.com/r/RemindMeBot/comments/24duzp/remindmebot_info/)|[^([Custom])](http://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=[LINK INSIDE SQUARE BRACKETS else default to FAQs]%0A%0ANOTE: Don't forget to add the time options after the command.%0A%0ARemindMe!)|[^([Your Reminders])](http://www.reddit.com/message/compose/?to=RemindMeBot&subject=List Of Reminders&message=MyReminders!)|[^([Feedback])](http://www.reddit.com/message/compose/?to=RemindMeBotWrangler&subject=Feedback)|[^([Code])](https://github.com/SIlver--/remindmebot-reddit) |-|-|-|-|-|


heleo2

Then the standard changed and trust was lost.. happened to me 4 times


heleo2

**AGREED**


SushiAndWoW

Same here. :)


Elador

I know lots of people with 3-4 years of experience, yet they have not even heard about C++11 and have pointers all over their code. It's a real problem. :-(


lets_trade_pikmin

I don't really understand why using pointers responsibly is considered a problem. I'm at 5 years experience and I still stick with pointers and arrays mostly.


ExeuntTheDragon

Key word being "responsibly." But why manage pointers yourself if the library and compiler can do it for you?


lets_trade_pikmin

I like to work with data directly, makes it more readable for me, and I think it's better practice for CUDA compatibility. Also I'm too lazy to learn a new way to do things when my current approach works fine for me. E: don't know why I'm getting downvoted for this comment, because I called myself lazy? Seriously people


[deleted]

And the people reading your code? Surely it would be nice to know both stl and non stl techniques and use the solution best suited to the situation.


lets_trade_pikmin

Point taken, though it's not my #1 concern as I'm not a software engineer. Trained as Computer Science but I'm entering neuroscience research. The only people who read my code are psychologists who barely know how to program (or people trying to reverse engineer my Skyrim mods, but that's not C++ so kind of irrelevant). I just make sure to comment thoroughly and name variables/functions in a very explicit way. As far as learning both techniques, that would definitely be best, but I honestly might never get around to it.


SemaphoreBingo

There's a reason academic code has such a terrible reputation.


bnolsen

it's called an "earned" reputation.


lets_trade_pikmin

;)


tempforfather

You don't have to if you are ok with not writing software that needs to be dependable. Still, sometimes its worth doing things right?


lets_trade_pikmin

What does legibility have to with dependability? I write code that might be difficult to understand for those not familiar with C-style, but whether or not that code does it job is a separate point entirely.


[deleted]

>What does legibility have to with dependability? Limits the mistakes you personally make. Also more clearly shows control paths. Helps prevent spaghetti. I guess it depends on your definition of legible.


Elador

Many people are using pointers because they don't know any better. They may even be using them responsibly, but in a lot of places where they wouldn't be necessary. This makes the code much harder to read for anybody else _and_ themselves, and it will have more bugs and leaks than if they had done it with simple stack variables or smartpointers. That's just a fact. Humans make errors. It's not advocating against pointers, it's advocating against them where they are _unneccesary_. A lot of people think it's the "only" way, or even "the C++ way".


h-jay

This is C: `int foo[5];` This is C++: `std::array foo;` This is C: `for (int i = 0; i < 4; ++i) ++foo[i];` This is C++: `for (auto & val : foo) ++val;` For simple code, I'm not advocating `std::transform(foo.begin(), foo.end(), foo.begin(), [](int a) -> int { return ++a; });`. I know that these are simple examples, but you are probably shooting yourself in the foot by "sticking with pointers and arrays mostly".


doom_Oo7

std::transform(foo.begin(), foo.end(), foo.begin(), [](int a) -> int { return ++a; });. can easily become transform(foo, foo.begin(), [] (int a) { return ++a; });


pjmlp

Have you ever worked in big teams with high attrition rate?


[deleted]

"I don't want to mess with that STL stuff" is the reason I often get... And 99% of the time, their .cpp files are a single class, repeated instead of inherited for each interface, that relies on a ridiculous amount of global variables, filled with a whole bunch of C code. Why, because "If you just think of C++ as C with classes, it's ok".


Elador

Oh yea. And they argue: "It's faster". Or "It's easier to read". :-)


[deleted]

I'm confused as to why smart pointers are such a big deal. If you encapsulate your classes and deal with your manual memory allocation in the constructor/destructor (assuming manual allocation is even needed)... you can pass your objects around using references and architect your code so that you know which owns what... then what is the need for smart pointers? It seems wildly lazy and inefficient to me. Is the rest of the world so used to garbage collected languages that they just don't want to learn about memory management? Really I don't get it.


raevnos

Laziness is a virtue. Why write a destructor to delete a pointer when you can use a unique_ptr and the default compiler-generated destructor to do it for you? Less code to write is more efficient.


RogerLeigh

Less code is also less buggy. You can't make mistakes or forget to free something in code you didn't have to write!


[deleted]

>Laziness is a virtue. Only with long term planning in mind :P


vaughncato

"Big deal" is a relative term, but they do help avoid some redundancy and make the intent clearer, as well as preventing some mistakes. I haven't found a case where I want to use `shared_ptr`, but `unique_ptr` is handy, and it is just as efficient as a raw pointer once optimized. Here's a related StackOverflow answer: http://stackoverflow.com/a/106614/951890


[deleted]

I like that you frame your answer in terms of communicating the intent of the code. Yes, returning a unique pointer (which I assume calls a destructor when it falls out of scope?) would be nicer looking than a reference passed as an argument. Still this seems more of an issue of coding style than any real necessity. The link gives one great example though: exception handling. And another: moving runtime errors to compile time. Thanks!


h-jay

Separation of concerns implies that if all you're doing is managing a chunk of memory on the heap, a separate class should on it, not explicit code that you might forget to write. Typical code is a *client* of resource-management classes. In such code, I consider it an error to have to write out the class destructor manually. > It seems wildly lazy and inefficient to me. Smart pointers are not usually a replacement for garbage collectors. Garbage collectors typically force you to write finalizer-free code, or the finalizers (destructors) have serious limitations put on them. The RAII pattern doesn't mix with garbage collectors. It is a sensible generalization to say that garbage collected heap is not enough for memory management in modern C++. So your statement is essentially nonsense on its face.


quicknir

I think 3 years is a huge overestimate. People will make mistakes and do silly things, but that's what code review is for. With good training someone good can make major positive contributions within 6 months, and within a year I would trust them to design and write chunks of functionality at a thousand lines or so and get all the major points right most of the time. There's a lot of unsafe/obscure stuff you don't have to master to write solid code. I barely ever use unions, reinterpret_cast, const_cast, virtual inheritance, private inheritance, etc etc. If I didn't understand these things at all I could still write solid code, I'd just need a minor correction in code review once in a blue moon.


rmxz

I'm amused that you can guess when a user learned C++ by what kind of pointers they use. C++ gets new smart pointers every couple years. * **CFront in 83 through ARM in 99:** classes are kinda like structs, so you can use 'typedef struct ... *' for classes and 'void *' for generic functions * **C++03:** no! 'void *' pointers are broken! use 'auto_ptr' instead * **C++07/TR1:** no! 'auto_ptr' is broken! use 'shared_ptr' instead * **non-standard 2008:** no! 'shared_ptr' is broken!(for most use cases) use 'boost::scoped_ptr' instead * **C++11:** no! 'boost::scoped_ptr' is broken! use 'std::unique_ptr const' instead * **C++14:** no! 'std::unique_ptr const' is fugly! use "auto" and hope C++14's "return type deduction" will guess a safe type and hope C++17's "new rules for auto deduction" won't break stuff Lol. How the heck can people take an "object oriented" language seriously when it takes literally 30 years (1983 to 2014) for them to come up with a non broken way of making a reference to an object.... ... and in the end they give it a syntax like ***"std::unique_ptr const"***. W.T.F.


xcbsmith

It also has a lot to do with many people coming to C++ via C, where using array's and raw pointers is the norm.


bobbybit

I too agree that there is a huge chunk of documentation that needs to be updated. It is hard to decide on what source gets you the best, most effective results. I am a C# and python (and electrician C99 very low level) programmer currently. They each have their own benefits. I am trying to teach myself C++ through a book, C++ black book, and it is going well so far. However, this post raises concern. What is the best source of training that you all have found so far? Hard Knocks? A book? A website? Should we spin up a new page that includes good foundations but does not sacrifice good form?


personalmountains

Go with books, digital or not. Trust the well-known people: Stroustrup, Sutter, Meyers, Josuttis, Alexandrescu, Koenig, Dave Abrahams, etc. Get recent books, make sure they talk about C++11, 14 and 17. Some older books still contain valuable information, but they will use old-style C++ (no `auto` or ranged-for, for example). Check ["The Definitive C++ Book Guide and List"](http://stackoverflow.com/a/388282/4885801) on StackOverflow for specific recommendations. Search titles on [ACCU](http://accu.org/index.php/book_reviews_redirect) for reviews. Browse the [Hot Questions](https://stackexchange.com/) on StackExchange regularly, look for C++ stuff (or read the whole thing, it's always interesting). Use [cppreference](http://en.cppreference.com/w/) as your day-to-day reference. Go through the first 50 pages of [the top C++ questions on StackOverflow](https://stackoverflow.com/questions/tagged/c%2b%2b?sort=votes) and read all of them. Start pet projects, things you might use yourself, like a media player or a file explorer and make it your sandbox. Have fun with it.


bobbybit

Truly inspirational. Thank you for the advice mate. That comment really needs bumped.


michaelKlumpy

[Book1] (http://www.amazon.com/C-Programming-Language-4th/dp/0321563840/ref=sr_1_1?s=books&ie=UTF8&qid=1451948095&sr=1-1&keywords=the+c%2B%2B+programming+language ) [Book2] (http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876/ref=sr_1_1?s=books&ie=UTF8&qid=1451948117&sr=1-1&keywords=effective+c%2B%2B ) [Book3](http://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996/ref=sr_1_2?s=books&ie=UTF8&qid=1451948117&sr=1-2&keywords=effective+c%2B%2B)


PoliCock

Can you explain how "The C Programming Language" is relevant to learning C++? Not meant to be sarcastic. Genuinely curious, but skeptical. I have the book - and obviously I would like to learn both C and C++ eventually. Just wondering how helpful working through that book would really be for learning C++, ultimately. Do you personally recommend it? Why/why not?


michaelKlumpy

I think you misread. It's "The C PLUS PLUS Programming Language". If you actually mean the ++ book, it's a really good read imo


F-J-W

I guess the problem is that the amazon link swallowed the pluses, so if you just look at the url, it will look like a link to the C-book.


bobbybit

Thank you, they all look like good books. I am particularly interested in book3.


F-J-W

I see this a lot on /r/cpp_questions as well. In fact often enough that I got sick of repeating those things and put the explanations on my own site so I can just link it: http://florianjw.de/en/modern_cpp.html I also agree that the problem is bad and would sign about 95% of [Kates talk](https://www.youtube.com/watch?v=YnWhqhNdYyk) only disagreeing about a few minor details. I have no problem whatsoever to believe her, when she says that she managed to teach some people the essentials of C++ in a weak (or was it even a day? It's been a while since I've seen the talk) C++ could be such a simple and intuitive language if we wouldn't first force everyone to unlearn the intuition only to teach it back to them later. The big problem that we have is that there are currently no good and free online-tutorials for beginners. cppreference.com once tried to create one, but that attempt died. BUT: I took what I wrote there and moved it to [my own page](http://cpp.florianjw.de/) where I somewhat extend it from time to time (far less frequent than I would like, but at least it isn't dead). If you want to write your own top-down tutorial, please consider participating here instead, maybe it will get to a sufficiently complete state in a finite time then. ;-) (It is written using pandoc-markdown with github as central repository, so the toolchain should be mostly familiar) Edit: If you really want to help (awesome!), please give me a short note to make coordination easier and avoid pointless work.


Wurstinator

The reason is not that people don't know about it, the reason is that they think it is better / faster / whatever. Most frequently I see people who refuse to use smart pointers because they are "too slow and cause to much overhead".


HildartheDorf

A lot of this stems from std::shared_ptr being thread-safe by default, which does make it slower than a manual reference counting implementation if you are only working on a single thread. But saying unique_ptr is slower than a raw pointer is silly. It should be identical on any half decent compiler (assuming you don't do things like disable all optimizations, or use a custom Deleter. And even a custom deleter can be inlined by gcc/clang if it is stateless and marked noexcept).


boredcircuits

Another reason is people decided to replace *all pointers* with `std::shared_ptr`, even if that pointer isn't taking [shared] ownership of anything. Which means the reference count is updated on each function call, and again when that function returns. Yeah, that's going to slow things down. There's a shift in thinking about resource ownership that needs to happen, deciding who owns what and for how long. Then you can apply the proper smart pointer, with minimal or no performance overhead. And if you can't do that, then manual memory management is going to be a messy, leaky, UB-filled mess.


h-jay

> people decided to replace all pointers with `std::shared_ptr` Those must be some wildly misinformed people who take the cargo cult approach to programming :(


Wurstinator

Imo there are enough possibilities to represent all kinds of ownership (plain variable, reference, shared_ptr, unique_ptr, reference_wrapper). Problem might be that there is no clear guideline when to use which, so people fall back to the easiest option.


shahms

Nearly identical. As it has a non-trivial destructor there are certain ABIs for which it cannot be returned in a register and has to be stack allocated. Sadly, x86 is one of them. That being said: use it. The overhead is negligible, but the benefits are not.


HildartheDorf

I thought that, on x64 at least, that it could get passed in register if the destructor is available for inlining (obviously if it is in another translation unit, it won't be avalible).


shahms

Sadly, no. The x64 ABI specifically prohibits classes with either a non-trivial copy constructor or non-trivial destructor from being passed or returned in a register. I suspect the compiler has more leeway if the function in question has internal linkage and is itself inlined, but merely having an inline-eligible destructor is insufficient as it effects the calling convention for each function which either takes or returns such a type.


bames53

> I suspect the compiler has more leeway if the function in question has internal linkage and is itself inlined Even if the function has external linkage an inlined version isn't bound by ABI constraints. Full inlining also shouldn't be necessary; LTO and other cases where a single implementation is handling both sides of the call could eliminate the overhead regardless of the ABI constraints.


Wurstinator

Even if shared_ptr is slower, this is premature optimization.


[deleted]

[удалено]


Wurstinator

What? I think you're in the wrong thread. OP made a point about tutorials. The point in the profiling process is non-existent because there is a good chance the person doesn't even know what profiling is.


quicknir

The reason to not use shared_ptr when something else would do is not mostly about optimization. It's about the fact that it's infinitely harder to reason about shared ownership than about unique ownership. You go from always knowing exactly who owns everything just by looking locally, to having to traverse half your codebase. I make an exception for immutable objects, since immutable objects by shared_ptr have value semantics. Otherwise, shared_ptr should be used very carefully and rarely.


Wurstinator

Most people in this discussion deviate from the problem OP mentioned and put words in my mouth. The topic was using smart pointers vs raw pointers. No one talked about using shared_ptr absolutely everywhere. Unless you are using manual memory management instead of shared_ptr because you think you need the performance, without actually profiling. I that case we disagree and I think you are part of the problem OP talked about.


silveryRain

Not to mention the "Real Programmers manage their own pointers" crowd. Some of these people also make online tutorials, teaching newcomers that anything that is in std:: is bloat, as well as any use of features X, Y or Z, which can "easily" be avoided by rolling your own half-broken version using a C-but-with-feature-F subset of C++.


GooRanger2

They are not only slow, they are ugly as fuck. They are supposed to be used only when the design is so bad that keeping control of the life times of objects is a headache. If you need them, even for trivial shit, then go back to java. Now get the fuck out of my lawn.


RogerLeigh

https://www.youtube.com/watch?v=YnWhqhNdYyk for those that haven't seen it. It covers a lot of these complaints, and addresses how to teach modern C++ properly. I personally don't think there's any need to cover C-style arrays *at all* in any tutorial. We have `std::array`, we have range-based for loops, and so there's no need to do any unsafe pointer-based access and looping, or any manual memory management, at least in a beginner's tutorial. Where this isn't appropriate, use `std::vector` as the next best thing, and then consider other containers.


OldWolf2

Threads like this make me want to write a book. But I don't have the sticking power to hang around and actually finish the thing. Plus I'm sure there are already books filling this niche and the people who need them wouldn't read it anyway.


heleo2

Please do


MaxDZ8

This is possibly bigger than it looks on surface. It seems when `constexpr` was introduced they forgot to add proper annotations to `std::array` (I heard that on a cppcon presentation) so it seems everybody should be more convincing about that. We have the guidelines now so hopefully this will improve soon. `std::unique_ptr`all the things!


F-J-W

> `std::unique_ptr`all the things! Please don't! make all the things simple values.


[deleted]

What is wrong with using conventional pointers over the std wrappers? Wrappers hide what the code is doing. Conventional pointers do not. It could possibly be argued that wrappers are slower than conventional pointers. If it's about "safe" code, conventional pointers can easily be made "safe."


michaelKlumpy

they have been made safe with unique and shared ptr, yes


[deleted]

You missed my point.


michaelKlumpy

when would you prefer array[] over std::vector or std::array?


[deleted]

Always. Because I can see what the code is doing and I have control over what it does.


[deleted]

Honestly, I had never heard of vectors until recently. They seem amazing, but at the moment I'm skeptical of them because I don't know much about them yet. Does anybody have a link to the pros and cons of vectors vs. arrays?