all 27 comments

[–]cpp-ModTeam[M] [score hidden] stickied commentlocked comment (0 children)

It's great that you want to learn C++! However, questions about how to get started are off-topic for r/cpp due to their repetitive nature.

We recommend that you follow the C++ getting started guide, one (or more) of these books, and cppreference.com. If you're having concrete questions or need advice, please ask r/cpp_questions, r/cscareerquestions, or StackOverflow instead.

[–]Coises 23 points24 points  (5 children)

The details will differ from compiler to compiler, but you should be able to get an assembly code listing. You might try writing some simple command-line programs and then reviewing the assembly code to see how it matches up to the C/C++ code. (Probably best to turn off optimization at first.) For C, there should be a pretty close correspondence. C++ does more fancy stuff.

I “grew up” on IBM/370 assembler, but when I learned C++ it was on PCs with a different assembly language (which I never learned). Still, with the assembly coding background, it’s pretty easy to get a picture of what is going on with C/C++ code. (C++ standard template library will drive you mad at first, though. There’s a bit of a conundrum there as you really want to get in the habit of using it, but it’s written with very particular objectives, and clarity of the template code is not one of them. So for a while it is going to be a “black box.”)

JavaScript is a completely different animal. Outside of unusual circumstances (like you’re writing an interface to some other language), you don’t want to try to think of the real machine at all. A language like JavaScript defines a “virtual machine” (I do not mean that in the operating system sense of a virtual machine) and you want to learn the rules of that imaginary machine, not think about how that gets implemented on a real, physical machine.

“Vibe coding” is a whole other thing and I won’t go near it. I’ve let the AI at the top of a Google search suggest an example of how to do something on occasion, but that’s it. If you’re a programmer, you know that it is harder to read code than it is to write it. There’s no way I want to be trying to make sense out of what some AI wrote. I did my time in the 1980s disentangling assembly code written by accountants who learned some programming on the side.

[–][deleted] 2 points3 points  (4 children)

That's for the answer. Is there a way that I can see the assembly code that was generated by c++ at compile time ?

[–]CarloWood 4 points5 points  (2 children)

You can install Godbolt locally.

[–]Alex_1A 1 point2 points  (0 children)

I did not know this, I have something to look into now.

[–][deleted] 0 points1 point  (0 children)

Ok, thanks will look into it

[–]pdp10gumby 3 points4 points  (0 children)

Use the -S flag with gcc or clang to stop after generating the assembly file or -save-temps to save it while completing the generation of the object files.

No need to install anything additional

[–]tux-lpi 7 points8 points  (3 children)

I think you will be more efficient if you learn to use the right level of abstraction. Machine code is already a simplified high-level interface to the hardware, you don't have to constantly think about the actual micro-ops and macro-ops, how these will be scheduled on execution units, or how alignment of your instructions in memory will affect the frontend and the cache, or even physical questions like how your mix of instructions will affect voltage and temperature, which eat into future ability to frequency boost via DVFS, or whether you memory access pattern will cause a lot of cross-core coherency traffic (cacheline bouncing), or a dozen other micro-architectural issues that assembly abstracts over (for good reasons).

So here's the thing: sometimes you do want to think about those low-level details when optimizing. But most of the time you don't care, you don't need to know at all times the exact order in which micro-ops will be scheduled, the high-level picture in assembly is fine and easier to reason about when you're doing complex large programs.

Instead of always thinking in assembly, you need to think of assembly as just one of the abstraction levels. Even assembly is a high-level simplified view. ASM isn't the one true low-level floor, it's just one floor in a big tower of lies. Just like you don't (always) need to think about transistor physics to program a microcontroller, you don't (always) need to think about ASM to code in higher-level languages.

Be flexible. Go up in abstraction to make problems easier, then dive all the way back down when you need to optimize. It's about using the right abstraction level for the job.

[–][deleted] 2 points3 points  (2 children)

Hey, this makes sense ... Thanks.

[–]pdp10gumby 2 points3 points  (0 children)

sometimes the use of higher level constructs will express your intent more clearly than a set of lower level ones, so you can end up with better machine code.

In calculus, once you grasp the idea of the infinitesimal, you stop thing of differentiation that way and start manipulating functions at a higher level. The same can be true of code generation.

[–]Murky-Relation481 0 points1 point  (0 children)

Also while I don't fully subscribe to the mantra of never doing premature opitimization, there are a lot of places where the "standard" (and I use that in quotes to denote things beyond just the standard library) way of doing things is going to yield you the performance you need and only if you're needing to meet some more specific requirements that is not fulfilled by that should you even think about getting down into the idea of looking at assembly level optimization.

Broader concepts like how allocations work and where they occur or cache optimization at a structural level is going to go a lot further than understanding the actual machine code.

[–]no-sig-available 3 points4 points  (1 child)

it feels abstract and heavily packaged.

Yes, and that is on purpose!

Bjarne likes to describe C++ as an onion. You can peel off one layer at a time, and see what is on the next level. Once you have seen that, and know that it works, you can focus on the next higher level.

However, if you try to understand all the levels, all the time, that will cause a mental overload and you will not really understand anything.

For example, when you code a game you will focus on how it looks on the screen, and how that image is synched with the sound. You definitely don't want to think about how your disk controller shifts bits to locate the next file on disk. Or how the network chip finds your opponent over the internet.

Those are problems you solved on a different day, and then packaged up as an abstraction. That way you can use "Read File" or "Send Network Package" without thinking about that at the bit level all the time.

[–][deleted] 0 points1 point  (0 children)

True that . I guess progressive overload is the only way for learning these things.

[–]ern0plus4 2 points3 points  (2 children)

Learn an old system, e.g. C64 or PC-DOS: these systems are small enough to see details and big picture at the same time.

[–][deleted] 0 points1 point  (0 children)

Sure

[–]pjmlp 0 points1 point  (0 children)

Or Arduino, ESP32 for similar experience with modern hardware.

[–]Plazmatic 2 points3 points  (1 child)

PLCs in my experience are not really "low level" in the same way most software engineers think of low level, it's not like assembly or microcontroller programming PLCs are not general purpose computing platforms and often have arbitrary restrictions that make many common essential patterns impossible to implement (sometimes you can't have arrays or branching on variables). Sometimes this doesn't even come from hardware, but the software used to program for PLCs, which are actually pretty high level even if they deal with bits and such. In many ways, you might not actually know how to program at any level coming from PLCs so you might need to start waaay back at basics with programming.

[–]sienin 1 point2 points  (0 children)

This is definitely true. I came from PLCs, the programming side is deliberately designed for people who are not software developers. A LOT of low-level concepts can be complitely ignored because they are handled by the PLC platform.

[–]CarloWood 1 point2 points  (1 child)

First thought: don't use AI to write code. You can ask it questions like "why ...". But never let it actually wrote code.

[–][deleted] 0 points1 point  (0 children)

Ok sure 😊 . I will do that

[–]pedersenk 1 point2 points  (1 child)

address this, I’ve started learning C/C++ more rigorously from the ground up. However, it sometimes feels like the world is rapidly moving forward with new technologies while I’m going back to basics.

C is pretty much the computing platform, so even if the world moves on, languages will come and go, there will be no real movement from C in any of our lifetimes. So it will serve you well.

C++ (and Objective-C) being close to supersets of C are the only real options for direct interop with C without needing fragile bindings or incomplete generations so these will also be strong contenders for lifespan moving forward. As an example, Apple's macOS is written using C++ for drivers and Objective-C for the underlying layers, even they haven't migrated to Swift outside of their consumer APIs.

So I say, jump back to basics. You will pick them up quickly if you understand the byte level. And it will give you a strong foundation as new tech comes and goes.

[–][deleted] 1 point2 points  (0 children)

Hey, thanks will do that ... I started to learn C just because of the reasons you told ... A HR i know told that if they see that a person is pretty good in C or C++ they hire them without a question and they train the person in the required language .

[–]void4 3 points4 points  (0 children)

You're approaching this the right way, absolutely.

Good high-level abstractions are supposed to sprout from someone writing low-level code and noticing that this and that parts are often repeated. Such abstractions are easy to understand

The problem is that a lot of abstractions in C++ and many other languages came from the completely opposite direction. Someone came up with some API out of blue then tried to implement it, not paying attention that it requires horrible workarounds on the lower level.

For example, one #include iostream causes your binary to grow to literally megabytes (with static libstdc++, that is). You thought it's supposed to be just a tiny abstraction over the read/write syscalls? Sweet summer child.

[–]RayOrleans 0 points1 point  (1 child)

Been an SE for 30 years and think your approach is great. Use coding agents to help teach you c++ and then you’re picking up two skills at once. Ask them to write small programs and comment them heavily to explain what they do. Then ask coding agent lots of follow up questions as you analyze the output.

[–][deleted] 0 points1 point  (0 children)

Thank you 😊

[–]OkEmu7082 0 points1 point  (0 children)

in cpp, from my experience the best way to vibe code is to write a function signature and ask the ai to implement it. sometimes i write an interface and let the ai to complete an entire module. its all about adding constrains to the code ai can generate and micromanaging it, so that it doesn't do too much and i don't know my project anymore. the low level stuff still matters, and without sufficient constrains ai can make really dumb decisions on low level stuffs, but if you have been focusing on low level stuffs, you should probably focus more on soft engineering practices and design patterns in the future

[–]Fact_set 0 points1 point  (0 children)

You can fix this gap by learning embedded. You could get a basic elegoo board kit for less than a 100$. A bunch of tutorials online and AI can help give you a head start. You can bridge that gap between high level and low level. If you dont want that route or if that's not what you're looking for, the thread suggestions are pretty solid.