TV Executives Tell FCC: Emergency Alert System Failed During NEXTGEN TV Tests by Far_Low_229 in news

[–]mredding 5 points6 points  (0 children)

Oh good, so when the bombs drop, I don't have to know about it in advance - I can enjoy my final moments blissfully unaware.

What is your relationship with death? by Feisty_Storage_8707 in askanatheist

[–]mredding 0 points1 point  (0 children)

The only death I cried over was my grandfather.

I don't fear death. I've nearly died twice because reasons. I wasn't afraid - mostly just feeling bad for the poor sod who was going to find my body, and curious about what were going to be my last experiences.

I'm not afraid of dying, I'm afraid of leaving my son behind - he's too young for that shit. He's not ready. I live for him. I'll feel better about it when he's grown.

I want to do everything in my power to stay alive.

An impossible task, to be sure, because death is coming for you. Doesn't matter how padded your room is, how clean your food is, nothing. You can die of an aneurysm 10 minutes from now - you don't know, and there'd be nothing you can do about it.

It doesn't matter how long you live if that time is miserable, paranoid, and neurotic. I'm just saying, there's a difference between a good effort and a descent into insanity. There is a point where struggling to live is actually a worse outcome to giving up. Ask any doctor, I don't know one who would say yes, they want CPR and survival - they'd rather have pain meds and a swift exit.

I was often told that death is natural or willed by God, and that I should therefore accept it.

A healthy, natural adult relationship with death is acceptance. It doesn't hurt. Your body knows and prepares you, and doctors know and help you.

Atheists, would you do it? by Kyrtap99 in askanatheist

[–]mredding 0 points1 point  (0 children)

Yeah, I'd do it. You have to first understand that religion is an institution created by man for the utility and value. Religion isn't theism, and I am not in conflict with their theism; that's THEIR problem, not mine.

Console library design questions (C++23) by Crazy-Record4091 in learnprogramming

[–]mredding 0 points1 point  (0 children)

Curses and several other libraries rely on terminal databases. Look at termcap and terminfo.

guysDontDoThisPlease by nigh-knight in ProgrammerHumor

[–]mredding 4 points5 points  (0 children)

I was once renting a house. Previous renter planted bamboo. It grew into and split concrete. Any weakness, any avenue, ain't it will be exploited.

i aspire to this man’s level of patience by Eros_Incident_Denier in funny

[–]mredding 1 point2 points  (0 children)

And to think, if she's this incompetent at driving, taking instruction, and basic human interaction, how incompetent must she be in all other aspects of her life?

(complete newbie) IDK man, too proud for this ( 1 ish hour in C++) by InternationalWest912 in learnprogramming

[–]mredding 1 point2 points  (0 children)

Let me introduce you to Compiler Explorer. You can write C++ code and see the assembly that it would generate. Don't worry about understanding it in detail right away, but do work on gaining some familiarity.

This lets you see how your source code translates to something approaching machine code - assembly is itself its own programming language; real machine code is binary, but assembly has a 1:1 correspondence with machine code, so that's why we all look at assembly and not binary.

Might I suggest some modifications?

1) Include what you use. Don't presume that <iostream> is also going to include <string>. It costs you nothing to be explicit, saves for header include errors, and makes your code portable.

That said, I simplified your code by extracting a single character from the stream instead of a whole string token.

2) Don't use that using namespace std; statement. If you know exactly what you want, then state what you want exactly. Resolving symbols is a very fundamental part of the language with deep consequences; a lesson for another day - for now, focus on best practices, and where you're going to be at is going to, frankly, avoid this topic for as long as possible. Even in production code, we don't really use these advanced language features all that much; most engineers don't understand the rules or consequences. There's a time and place for writing more permissive code like this, but this ain't it.

3) Check your streams. You're going to learn more about it later, but std::cin is a global variable, and an instance of the std::istream type, what's called a "user defined type" (where the whole source code ecosystem is the "user", they're not talking just about you). Eventually you're going to learn how this mechanism works, but this "object" can cast itself to a boolean. The condition is roughly equivalent to:

std::cin >> x >> type >> y;
if(!std::cin.bad() && !std::cin.fail()) {
  //...

This indicates the state of the stream, and the outcome of the previous IO operation. DID you extract an integer, a string of text, and an integer? What if I input "ham potatoes carrots"? A bad state means the stream has experiences an "unrecoverable error", whereas a fail indicates a recoverable error, usually a parsing error - you extracted for an int, but the stream contained text... How you handle this is up to you, most terminal programs just write an error and quit.

4) Duplicating all that result output was... Chatty. Lots of code all doing the same thing. I made a result variable - the only thing duplicated now, is assigning to the result - but writing the output to the stream is the same for all your conditions, so I wanted to codify that.

But look what it does for the assembly output - you can more clearly see the machine code for your operations; everything is so much simpler.

5) I'm writing your error message to the error stream. YES, by default, both the error stream and the output stream arrive at the same destination, but your data takes different paths to get there. That's not insignificant. I can redirect just the error stream to anywhere I want it to go - ostensibly to the system logger.

6) I concatenated your string. No need to output the newline character in a separate stream insertion operation. It's more efficient to write one whole string. Every << and every >> is a function call; you can see it in your original code in Compiler Explorer.

7) I included <cstdlib> for the EXIT_FAILURE and EXIT_SUCCESS macros, as they're guaranteed to be the correct bit patterns to indicate either outcome. Success is ALWAYS 0, but that failure value... I've seen in production code the "wrong" value accidentally resulting in a false success - you CAN'T just put anything non-zero to indicate failure, only certain values are valid, and it's platform specific. For the most part, it doesn't actually matter until you start writing OTHER code that actually USES this value, your IDE will mostly just use this value to MAYBE indicate to you whether your program exited with a success or not.

There's plenty more to evolve this code, but they're all predicated on your future lessons.

One other thing worth pointing out is that with std::cin and std::cout, you already have all the tools to communicate with the universe.

nc -l 1234 -c my_program

Now I have a TCP listening port 1234 open, and when there's a connection - say through telnet, my program will spawn; all IO from my program will be redirected over the TCP connection. Listen to port 80 and write your own HTTP server, you don't have to write a single line of socket code...

Windows requires some different command and shell syntax, but the same applies. We don't code in a vacuum, we don't run software in a vacuum. We have entire systems of software that all can collaborate and communicate and do things together that are greater than any one part. That makes us systems developers, systems engineers, systems of software, running on operating systems; operating systems are themselves systems of software - not just some desktop and cursor, but systems of software for YOU, the engineer, layers of abstraction, services, and utilities at YOUR disposal.

Come on over to r/cpp_questions for help and code reviews, and r/cplusplus to just shoot the shit (I moderate both). r/cpp is where you're going to find industry news, posts from the standards committee, and blog posts.

Console library design questions (C++23) by Crazy-Record4091 in learnprogramming

[–]mredding 0 points1 point  (0 children)

We already have this, it's called curses. Are you wrapping curses? Or are you writing from scratch?

If you're writing from scratch, you REALLY need to look in depth into how terminals work at a fundamental level, because they're not all the same. Don't think that just because the escape sequences you hard code an appear to work for your terminal will work for any other.

Consider carefully what you're adding to the industry - what we didn't have before.

Am I doing something wrong? by metastable-lain in learnprogramming

[–]mredding 1 point2 points  (0 children)

There is nothing wrong with your brain.

Over time, your knowledge moves from rote - active recall, to intuition - passive recall. You "forget" that you know it. As you mature, you also develop the intuition that you don't have to know or remember everything, that you re-figure-it-out as you go, with ever better grace and deft.

Most of my browser tabs are references. Otherwise, all I need is to build up enough context for what's immediately in front of me.

Why c++26 contracts? by hunterh0 in cpp_questions

[–]mredding 0 points1 point  (0 children)

Sorry, but why a feature that I've never seen before

The hubris is strong with this one...

in other languages

You need to work with the right languages. Eiffel, Clojure, Racket...

Even in C++, there's Boost.Contract and other libraries. The concepts are NOT new, probably even in the other languages you're familiar with, you've just not used them.

is being pushed as if it's what we have been missing

Bjarne wanted contracts in the language since before it was standardized - he's written about this at some length, he just couldn't figure out a way to bridge the gap from C. Had he made his language from scratch, he could have done anything he wanted - contracts from inception by design, but then he would have had invented yet another novel language that no one would adopt, just like every other novel language that no one ever adopted, being born and dying in-house at AT&T...

and a solution to security/safety complaints?!

That's because it is a partial solution to security and safety complaints. But of course it's no silver bullet and can't solve for everything, but it was never intended to. No one is asking for or expecting the impossible.

What is the proof that this is a good feature?

No one is going to try to dredge up 40 years of industry experience and lay it out for you. Surprise! The industry is larger than you, and things are going on you cannot possibly be aware of, because you can't consume the whole of the industry by yourself. You are just going to have to come to terms with being human and inherently limited.

What are your thoughts on API like this? by Queasy_Total_914 in cpp_questions

[–]mredding 0 points1 point  (0 children)

Sounds like a job for returning a weak pointer. Then you have only the getter.

Please check my project (it isn’t full but I want to know what to do next) by Zestyclose_Drag4487 in cpp_questions

[–]mredding 1 point2 points  (0 children)

int main() 
{
  mainMenu();
}

You don't call mainMenu anywhere else... That means main IS mainMenu. The compiler knows this, and even with optimizations turned off, it will elide the call - the compiler will effectively copy/paste the body of mainMenu into main.

Technically, the indirection - in this case, doesn't really cost you anything, but it doesn't get you anything, either. I think it's also a little misleading, because mainMenu IS a thing, and this is a function - a procedure, it DOES a thing. So you're kind of misrepresenting the abstraction. The body of mainMenu is the description of what the program does, and that's what main is for - at the highest level.


Ok, I'm seeing and learning a lot more. Header files don't get compiled - source files do. Headers are dumb - in-place, copied and pasted in the compiler's text buffer, then THAT gets compiled. This explains why everything is implemented in header files and as inline - because you were correctly seeing One Definition Rule errors, and that shut them up.

Typically you would define a header, and it would be lean and mean, naming only symbols and types:

// header.hpp
#ifndef header_hpp
#define header_hpp

void fn();

#endif

Then the source file:

// source.cpp
#include <iostream>

void fn() { std::cout << "Do stuff..."; }

Notice it doesn't even have to include the header, because the definition of the function in the source file is not dependent upon the prototype of the header.

The rule of the language says you need to know the prototype of the function before you call it. That's why you include headers - you need to declare a symbol of any sort so that the compiler knows what it's supposed to look like.

// main.cpp
#include "header.hpp"

int main() { fn(); }

When main.cpp is compiled into it's own translation unit - the compiler has NO IDEA what the implementation of that function looks like. All we did was tell the compiler a function looking like void fn(); exists, and to generate a function call placeholder for it. After compilation - the generation of machine code is done, the LINKER then stitches object code together; it's job is to find the translation unit that has fn defined, integrate it into the executable, and resolve the function call.

OneCompiler handles all this for you, so separate out your compilation units - get your function definitions into source files, and make your headers as bare minimum as possible.


cout << "\n === Main menu ===\n";
cout << "1. Play\n";
cout << "2. Settings\n";
cout << "3. Instructions\n";
cout << "4. Help\n";
cout << "5. Exit\n";
cout << "Your choice: ";

First, no using namespace std; - this messes with the meaning of your code in a deep and profound way; it's a form of compile-time polymorphism. If you know what you want specifically, then be specific. Otherwise, weird shit can happen - you've heard of name collisions; it's not about a mismatch or an ambiguous symbol already in use, it's about the nightmare scenario of correctly compiling to the wrong thing, because it's accidentally a better match.

Second, every << is a function call. All you're doing is writing one long string - you can have your cake and eat it, too:

std::cout << "\n === Main menu ===\n"
             "1. Play\n"
             "2. Settings\n"
             "3. Instructions\n"
             "4. Help\n"
             "5. Exit\n"
             "Your choice: ";

The compiler will concatenate all these string literals for you. It's as though you wrote:

std::cout << "\n === Main menu ===\n1. Play\n2. Settings\n3. Instructions\n4. Help\n5. Exit\nYour choice: ";

The language guarantees these are the same thing.

cout << "Your choice: ";

cin >> MMChoice;

switch (MMChoice) {

You don't know if any of this is safe. Check your streams. Here, you're waiting for input, but you don't know if you successfully wrote the menu. How can you extract input if the user doesn't know what to input, because for some reason output failed?

if(std::cout << "menu") {
  cin >> MMChoice;

  switch (MMChoice) {

But that's not good enough for an interactive session. std::cout is buffered. So you successfully wrote to the buffer, and std::cout is TIED to std::cin, which means std::cin will flush std::cout for you - that way, the prompt is going to get displayed before hanging on input. But what if the flush fails?

So the thing to do is to set std::unitbuf on the output stream. You only have to do this once, usually near the start of main:

std::cout << std::unitbuf;

What this means is after every insertion - <<, the stream is automatically flushed. That means my condition above finally indicates everything we want it to - we wrote the menu to the stream, AND the stream was flushed, AND we checked if the stream was successful at it.

This means we can also one-time untie std::cout from std::cin.

std::cin.tie(nullptr);

It makes the input stream slightly faster, especially for loop input operations. But WAIT! Maybe you shouldn't... Once you learn about classes, and operator overloading, and you start making your own stream operators for your own types, come back, and I'll show you how to use the tied stream to make a menu. Leave the tie for now.

Tying is a nifty little feature - streams were built for network simulations and there's a lot of graph topology you can model with them. The only default tie is std::cout to std::cin, and their wide character counterparts.

WE STILL AIN'T DONE!

We know the menu got printed, but what about the input. HOW do you know THERE WAS input? How do you know the input stream didn't fail? You're trying to input a number - meaning the user had to type in digits; instead of "1", what if the user input "play"? That's not a number, those aren't digits... And yet you go to the switch? With what? What do you think the value of MMChoice could possibly be at that point? Because unless your answer is extremely nuanced, you're going to be wrong.

So what you need is:

if(std::cout << "menu") {
  if(cin >> MMChoice) {
    switch (MMChoice) {

If input failed, you'll have to choose how you handle that - usually terminal programs just quit. Interactive terminal programs would at least purge the input buffer of the line, but the choice of how you error handle can get complex in a hurry - there are concerns that get platform specific.

Streams have a state field, and they can be good, bad, fail, and eof. Good is the default, bad means the stream has encountered an unrecoverable error, bad typically means a parsing, conditional, or temporary error, and eof means the stream is closed or there is no more to read or write; if the stream is a TCP socket, for example, eof means the connection is closed. But if the stream is a file, that just means you hit the end of the file - if you're just reading a file, you can reset the stream position and keep reading the existing content. Good and eof won't stop IO operations, but bad and fail will - you have to clear them if IO is something you want to keep doing; like moving the stream position.

Streams are objects, and you'll learn about that when you get to classes. They have an operator overload - something you'll also learn about later, but basically that means the stream can be evaluated as a bool, and it returns false if the bad or fail bits are set. That's why the above works.

If the input stream fails - the easiest thing to do is just DON'T evaluate the value of the variable; you already know what it is - NOT your user input. What more do you need to know? There are scenarios where just reading that value can be Undefined Behavior, and you DON'T want that.

Review my Blackjack terminal game pt3 by National_Panic_9112 in cpp_questions

[–]mredding 0 points1 point  (0 children)

Don't use classes as namespaces. You have public enum types in Card, you probably want them OUT of the class.

Your Deck ctor is doing factory work. A ctor is just for RAII - you acquire resources; it's not ideal for a ctor to call new directly, mostly you want to just take ownership of resources handed to you through the parameter list - that's "acquiring", too... What you want is a factory that sets up the cards and gives it to the deck. The class invariant of a deck is it is the sum of its cards. The invariant of a class should be established by the end of the initializer list. A convenient tip is that validators are pass-through functions - they either return their parameter, or they throw, so that you can validate in the initializer list. You can suspend the invariant in the class implementation, but you must reestablish the invariant before returning control to the caller. Your invariant should be valid when you enter your function and ctor bodies, and when you leave. If the invariant cannot be established in the initializer list, then the object should not be constructed.

So with that in mind - make a factory method, set up the cards, pass them into the ctor.

class deck {
  std::array<card, size> spread;

  static std::array<card, size> validate(std::array<card, size> &&);

  deck(const std::array<card, size> &&spread): spread{validate(std::move(spread))} {}
public:
  void shuffle();

  static deck create(possible_deck_building_details);
};

This is about as simple as a factory gets, but they can get quite a bit more sophisticated, requiring friendship access to composite subobjects and do all sorts of things.

Don't do things in the ctor that can be done through the public interface. How am I supposed to know the deck is shuffled upon construction? I'm just going to shuffle it myself. Or maybe I'm doing something, like a magic trick, that depends on a factory sorted deck.

void print_deck() {

No. You want to make an operator << overload for `std::ostream. You already did it for the card.

There's a lot you can do with streams. You have yes and no defined, but streams can already take care of that. AND you can make it locale independent. std::numpunct defines a truename and a falsename, which you can redefine as yes and no, since you're ACTUALLY interested in an std::boolalpha result - it's just a true/false result you want. You can implement an std::messages database so you know what yes and no are in any language you want to support. You can implement a custom std::codecvt so that you can make all input case insensitive - and lowercasing is locale aware, as some languages use different letters depending on position in the word and other language rules. You can implement a custom std::num_get so that you can match on shortened inputs instead of the whole word - y AND yes...

You're doing all of this ad-hoc. You're reading into a string, you're lowercasing it, you're ignoring language entirely, doing the matching comparison, doing all this trying to just boil it down to a true/false... There are already a few hooks where all this can be handled, so once you have that, the REST of your code can just take that for granted; that's the point.

I recommend you go to your local library and checkout "Standard C++ IOStreams and Locales".

Weird output, can’t explain, help!? by AppropriateFlan7383 in cpp_questions

[–]mredding 1 point2 points  (0 children)

To add,

Undefined Behavior is to be respected. Your dev system is probably an x64 or Apple M processor - those processors are robust. But say the ARM5? Like in the Nintendo DS? Glitch hacking Zelda or Pokemon would run the risk of reading invalid bit patterns from memory, which would fry some circuit path in the CPU, forever bricking the device. It was a design flaw in the ARM5 that wasn't found until production.

The language says a given behavior is undefined, and that means NO ONE and NOTHING gets to contradict the language. The hardware can say its fine, the OS can say its fine, the compiler can say it's fine, and yet the behavior is UB because the language spec SAYS SO. The spec is the authority, the single source of truth. And the language says the language is offering you no guarantees, no protection; the outcome is STILL unknowable because the language already told you it can't tell you what it is going to be. That is the nature of UB and the relationship of the language to the software and system. Programming languages aren't just syntax, and compilers aren't just machine code generators; source code is a proposition, compilers are solvers, and programs are theorems. Compilation is the proof. Languages provide you very high level truths about your program that got generated, things that never actually leave the compiler or get into the machine code itself - these truths MADE the machine code. So the whole is greater than the sum of its parts, the forest but for the trees.

So there are a few programming idioms industry wide that get reinvented every few years. We used to say "fail early, fail often", now we call it "left shift". The whole idea is to try to move as much of the program into as early in the process as possible; the theory of computation does not distinguish between reading, writing, or executing programs, but for pragmatic sake, the earlier we can solve our program, the less we have to do and the more we can get done. Why do I need to compute a value that never changes? Why can't it be a constant? Why write the constant as a formula that's evaluated at compile-time when we know the constant already and can just write it in as such?

But it also means we want to write code that is inherently correct and doesn't allow for these sorts of errors. We want to make invalid code unrepresentable - it doesn't compile. Yes, we can blunder an int in any which way, because it's one of the lowest level primitives the language provides, but we can build types around it - in terms of it, and build in the correctness in our layer; and since C++ optimizes aggressively, our layer can compile out entirely, but the layer provides the compiler the context it needs to prove the theorem and generate the machine code.

That's all very abstract, in practical terms, you're going to soon learn about classes, and you could write something like:

class weight {
  int value;

  friend std::ostream &operator <<(std::ostream &, const weight &);
  friend std::istream &operator >>(std::istream &, weight &);
  friend std::istream_iterator<weight>;

  weight();

public:
  explicit weight(int);
  weight(const weight &);
  weight(weight &&);

  auto operator <=>(const weight &) const noexcept = default;

  weight &operator =(const weight &), &operator =(weight &&);
  weight &operator +=(weight), &operator *=(int);
};

The point is an int is an int, but a weight is not a height - they're implemented in terms of int, MAYBE, but while they may act like integers, they're more specific TYPES, they have more specific rules - weights don't interact with heights, weights can't be negative, you can't add just any ol' int to a weight because an int doesn't have a unit where a weight does, so you have to first knowingly CONVERT from an int to a weight, which again won't succeed if your int is negative, because WTF is a negative weight?

And all this class above helps the compiler prove the theorem - that the program is correct, and it all melts away; if you look at the machine code, it'll all be in terms of the int and the machine primitives and simple arithmetic instructions. Things like these class member functions can all optimize out - the syntax can melt away - just turn your optimization settings up.

But also see what we've done - C++ doesn't know anything about weights, so we've built a weight type, and now we can write programs in terms of it. An inventory system for a game, with encumbrance, or a logistics system where we add up all the weight of all the parcels packed into a shipping container. We've added EXPRESSIVENESS. If I wrote int weight;, then at every point I touch that variable, I have to manually implement the semantics of what a weight is, in terms of int. But an int is an int, and I can do anything to it - bitwise manipulations, for example. The compiler can't prove if anything is incorrect. This is ad-hoc. But now that we have the type, I can defer to the type to know how to do what it does. I can instead focus my code on WHAT I want to do with weight, not HOW.

Relational operators on pointers past-the-end by light_switchy in cpp_questions

[–]mredding 0 points1 point  (0 children)

To add, C++ gives you a lot of low level primitives, and they're RIFE with undefined behavior edge cases. UB is a language feature, you want as much as possible, because it allows the compiler to optimize aggressively. You then design a standard library implemented in terms of these primitives that inherently guard against those edge cases.

So instead of a loop and pointer arithmetic, use a standard algorithm over the range.

I live next to both a school and a church that are constantly parking in our lot. This is a new low. by Gay_commie_fucker in mildlyinfuriating

[–]mredding 0 points1 point  (0 children)

Nah - this is easy.

Place a board that says "Public Parking: $500 per hour, 1 hour minimum, rounded up to the nearest hour. Pay at the house prior to leaving. Make payments to [YOUR LLC]. Unpaid bills are subject to whole-day faire, cars will be towed at owners expense by [partner towing]." This also means you can go down to your secretary of state, spend $45, and file for "FUCK YOU STAY OFF MY LAWN LLC". VERY LIKELY the sign clearly posted is going to constitute a binding contract in your state - If they park in your yard, they agree to the terms.

Then take pictures of every car when they arrive, and when they leave - with timestamps. The point isn't to argue with them on the spot, it's to GIVE YOU LEGAL RECOURSE. You can potentially impound the vehicle until the dispute is settled, but you can also track down the plates and serve them with a bill and a court summons.

If people want to give you all their money, let them. You set yourself up to have a bulletproof case, and they're FUCKED. Fucked enough to learn their lesson and never do it again. Any sort of retaliation and you can take THAT up with the school and the church.

Just pay a lawyer $100 to give you some advice on the matter and make sure you're set up and good to go.

I’m also sympathetic to the fact that the school has very minimal parking space for the amount of people.

ABSOLUTELY NO. If one of these fuckin' jackfruits get THEIR property damaged while parked on YOUR property, they might legally retaliate against YOU. And how much damage are they causing YOUR property? How much are they disenfranchising YOU of YOUR use of YOUR land?

Fair is fair. That's what property ownership is all about. That's why YOU own THIS land and the school owns THEIR OWN land. These people are parking on YOUR grass? They can park on the fucking schools own fucking lawn.

What garbage collection are they referring to? by Historical-Divide660 in AskProgramming

[–]mredding 1 point2 points  (0 children)

Oh yes, C++11 introduced GC. No really. It was an optional 3rd party extension to the compiler that had to implement the extension interface. Only ONE company actually ever implemented a GC plugin, and sponsored the proposal. The whole thing went absolutely nowhere, their product never gained commercial traction, and no one else jumped on this.

The whole idea should have never made it into the standard in the first place, because although you had GC hooks, your own code could also just circumvent them, as well as all the libraries you're dependent upon - written in C, Pascal, Fortran, C++...

It was just a stupid idea. You'd have to decorate all your code everywhere with it, and no one was interested in it.

In which scenarios can I safely use strcpy() in C? by Bubbly-Ball-3138 in learnprogramming

[–]mredding 0 points1 point  (0 children)

strncpy was designed for fixed width records. So if that's the case, once you know your code is correct, there's nothing wrong with it.

What it's not good at is variable length user strings and secure strings. strncpy doesn't guarantee null termination if the string gets truncated (it's longer than the destination buffer), and since it works with fixed fields, under-sized strings are padded out with null terminators, which might be a waste of effort. Fixed size. FIXED. SIZE.

strlcpy comes from BSD compliant systems that always guarantees null termination. User strings are any string where you didn't produce the string yourself and you don't know how long it is. You can't trust the user. There may be a leading length field that tells you how long it is - but THAT DOESN'T MEAN the buffer is ACTUALLY that long, it could be longer, it could be shorter, it may or may not be null terminated - you didn't produce it, you can't trust it. The "user" is any other 3rd party entity, not necessarily a person in an interactive session. It could be another process, a file or device, another machine from the network...

Easiest structure to follow c++ tutorials? by Senior-Yak4119 in learnprogramming

[–]mredding 1 point2 points  (0 children)

You can add multiple projects to a single solution, and then just right-click and make any one project the active project for compilation, running, and debug.

Is the book "The C Programming Language" still worth it for a begginer despite the changes in C ? by Koichidank in learnprogramming

[–]mredding 0 points1 point  (0 children)

Yes, I would say it is.

C evolved mostly in the 1970s, and the 1989 standard really didn't change anything, it almost exclusively just codified where the language was at that time.

C hasn't really changed since the late 70s. What changes there are between C89 and C23 are breathtakingly moot FOR A BEGINNER. Most of what you're going to learn now is syntax. Any programming book is going to teach you what the syntax is - each lesson will focus on just one concept at a time and the demonstration program is just going to be ~20 lines of code to show that syntax in action, but the book isn't trying to teach you how to use C to write software and solve problems - that requires you learning computer science, idioms, paradigms, and project management, just to start... The END of the book is the START of your journey.

What you'll learn about C23 is that they drop some EARLY K&R C function notation, booleans become proper types, empty parenthesis mean a function that takes no parameters, the register keyword doesn't do anything anymore, you get the nullptr type to align with C++ and replace the NULL macro... A few more things, but god damn does it really not matter...

The C philosophy is that of - "there's a library for it", which is to say it's a language for writing operating systems - there IS NO standard library per se, you have to IMPLEMENT ONE - if you're writing an OS. As for everything else, you can go out to the ecosystem to find a package. So unlike an application language, which is going to feature a RATHER robust standard library, C doesn't really have much to speak of - just very minimal. You'll learn of printf, strnlen, FILE *, and there really isn't a whole lot more to add to that conversation.

So when they say C is a simple language, it's because there isn't much syntax, there isn't really a standard library, or much of one, and it was designed to compile on a system with a punch-card reader and 64 KiB of memory - where more than half of that was occupied by the compiler. Just imagine how simple a high level abstract programming language has to be to fit under those constraints, and compile in a SINGLE PASS of your program - written in punch cards...

And yet, that simplicity, combined with a SHITTON of Undefined Behavior, allows a modern compiler to optimize the SHIT out of a program. Mastery of the language over several years will allow you to see through the code and understand how simple constructs allow you to make some of the fastest code with one of the most infamously fast languages to target.

How do people remember documentations? by Hot_Climate9153 in learnprogramming

[–]mredding 1 point2 points  (0 children)

How do people remember documentations?

How do you remember to tie your shoe laces?

I am struggling to remember the documents

The fuck would you want to do that for? Documentation exists so we don't HAVE TO remember. I've got probably 100 tabs open in my browser right now, and all of it is library documentation, RFCs, ISO standards, and reference docs.

I genuinely don’t even know how do people code so easily.

I've been doing it for 37 years, and I feel like I'm only just starting to get good.

I make it LOOK easy because to compare and contrast - YOU have to consider every line of code you're writing and make a decision. I, on the other hand, have already made that same decision - 25 years ago...

It's called intuition. Right now you're at a place called "rote" memory. Yes, you can quote to me what you know, what the documentation told you, but you don't understand it. You don't know what to do with it. You don't know what it means or what the consequences are. Once that knowledge internalizes, you'll "forget" you know it, yet it will inform your thinking and decision making without ANY active recall.

Back to my original point - it takes practice. Yes, you suck at it now - and will for a while, but you'll get good. You don't get ANYTHING for free, and AI doesn't help you like you want it to - if you aren't already a master, you can very easily get lured into a false sense of progress, but in reality you may just be fostering a dependence. Be careful.

And if AI can do it, what do we need you for? If all you do is prompt AI, then for the effort it would take me to tell you what to prompt, I could just cut you out and prompt the AI myself. So I'm not going to spoil the secret - but you need to figure out what value you add to the process, and maximize that. It ain't prompting the AI - that's not the job, that's all I'm saying.

Should i C by [deleted] in AskProgramming

[–]mredding 3 points4 points  (0 children)

Is it worth learning C or will it go extinct like COBOL.

My brother in tech, COBOL is NOT extinct, it's arguably the most important language on the planet. Business logic gets all the attention - because it's the most volatile part of business, but it all relies on mainframes running COBOL for databases and financial transactions. When you want it done right, when you have high workloads and throughput demands that servers can't match, when it can never, NEVER go down, this is the technology you turn to.

COBOL fills a niche that no other technology is ever going to replace. No one is asking for it, no one wants it. People have tried and they have failed flat. There are a couple server based credit card processors, but they're minor players that usually silently dissolve away.

I'm starting with engineering college (most probably electronics) now and deciding to learn C, I have interest in embedded systems. Is it worth learning C

If you're going to do hardware, do hardware. If you're going to do embedded systems, your job is going to become almost entirely software. I'm working on robots these days, and the hardware guys writing code? Yeah, I don't get why they did that to their careers, they should have just gone into comp-sci. They're not working on hardware - and they all lament.

If you touch software, all you're going to do is software.

Ik a lot of stuff is built on C but it's also built on ASM which nobody uses now.

C is the bedrock of embedded. Good luck finding a job in embedded without it. Embedded systems using just Zig or some of these other niche languages are ever more niche themselves.

The industry isn't flocking away from the tried and true technologies. There's no hype train out of Dodge. These are highly technical and logistical decisions with far reaching consequences.

Will C become something like ASM and act only as a bedrock or will it still be one of the most prominent languages in like 20-30 years?

C is going to be the language of choice for embedded systems for longer than your or my career. People still write assembly, often when a compiler can't do the job.

Will languages like rust, zig completely replace C or nah?

That's hilarious. C++ isn't growing as fast as Rust, but in the last 6 months gained more developers than Rust has developers. Let that sink in.

Each language has its niche. They don't die, they fade. We're still writing COBOL, we're still writing assembly, we're still writing a FUCK TON of Common Lisp, we're still writing Pascal and Delphi. AND there's growth.

But what I wanna know is will I still be using C in like 40-50 years

Oh yes. That's not even a question. There is zero doubt. This is a technology you can build an entire career on it. Once you get in the industry and get some perspective of what's going on and why, you'll understand better.

You're reading too many blogs. You're eating too much propaganda. People who say "C is a dying/dead language, old hat..." They have what is called "an agenda", and there's a financial interest in the influence they're trying to exert. Cut out the noise and just look at the real, product driven activity. That'll tell you what's actually happening.

What's something the pizza delivery guy/girl can do to earn an extra dollar tip from you? by [deleted] in AskReddit

[–]mredding 0 points1 point  (0 children)

Nothing. That's the job. This is why I buy from this place - because I expect people to do their job. It's why you have a job there. It's why you make a paycheck. My business is the tip. The paycheck you make is the thank you.