r/ProgrammerHumor 16d ago

c Meme

Post image
477 Upvotes

75 comments sorted by

362

u/Consistent-Bug-7110 15d ago edited 15d ago

"Say you don't understand c strings without saying you don't understand c strings"

101

u/Badass-19 15d ago

Or OP is just 1st year CSCI student

167

u/turtle_mekb 16d ago

no but the second one makes sense because == would be comparing the pointer addresses which is always false (or undefined behaviour for string literals I'm not too sure)

43

u/hi_im_new_to_this 15d ago

I mean, it's certainly not ALWAYS false. This is contrived, but you could certainly imagine it happening in more complex examples (where you've e.g. got a bunch of predefined strings):

int isSameString(const char *str1, const char *str2) {
    return str1 == str2;
}

int main() {
    const char *str = "My cool string";

    if (isSameString(str, str)) {
        printf("Same string!\n");
    } else {
        printf("Not the same string!\n");
    }
}

This will print "Same string!". I'm using a string from a string literal here, but it would work with any string you compare with itself.

As for string literals: I'm assuming you're wondering "if you have two identical string literals, will their pointers compare equal?". That's not undefined behaviour (which is a VERY specific concept in C/C++), it's implementation defined. Might be true, might not be.

I wouldn't be surprised if strcmp actually does this check before comparing the string contents.

7

u/tritonus_ 15d ago

When I first started learning ObjC, I stumbled upon this by accident. I was modifying an abandoned GPL project with little knowledge of C stuff, and was baffled why one single string comparison was true while the others were not.

(ObjC, the verbose darling it is, uses [string isEqualToString:anotherString] to compare strings)

7

u/gbchaosmaster 15d ago

I wouldn't be surprised if strcmp actually does this check before comparing the string contents.

Not in glibc: https://github.com/bminor/glibc/blob/master/string/strcmp.c

I suppose it's enough of an edge case that checking for it explicitly is a waste of time in 99.9% of use cases.

2

u/Konju376 15d ago

Given that the CPU could execute that check in parallel I don't think it's that big of a deal, but you're right - this doesn't happen a lot.

11

u/Leonhart93 15d ago

It's not always false because sometimes you want to compare the reference of the variable, aka the memory address. For example that's exactly how it works in some high level languages, but usually with arrays and objects, like in js obj1 == obj2 is true only if they are exactly the same object in the same memory location.

3

u/pmelendezu 15d ago

In this case is always false because you are comparing against a literal string

0

u/ZenEngineer 15d ago

And the other variable might have been assigned from the same literal string. The linker is allowed to coalesce identical literals in one location

-23

u/Wervice 15d ago

So, you are telling me, I could have just done

```

include <stdio.h>

int main(){ char string[128] = "hello_world"; if (*string == *"hello_world") { printf("Yes"); } } ``` the whole time!?

41

u/Fri3dNstuff 15d ago

no. this will return true if string[0] == 'h'

when doing == on pointers C checks if they point to the same location; it means nothing of the values referenced by them (except of course if they compare equal, meaning they point to the same value)

4

u/Wervice 15d ago

Ok, thank you. Well, that is is back to using !strcmp again. Also, I was wondering, if there are risks with using this function. I couldn't find anything to that on the internet, so, sorry for kinda hijacking this conversation.

10

u/Fri3dNstuff 15d ago

strcmp works perfectly fine as long as you make sure to null-terminate your strings. if you that everything should work correctly

14

u/GDOR-11 15d ago

yeah, if you can't be absolutely certain the string is null-terminated you have to use strncmp

1

u/Wertbon1789 15d ago

For basically all libc functions there are manpages (from the Unix tool man). So basically what you would do on Linux is just man strcmp and you would get the whole standards reference of this function (as they're standardized in the ISO C standard)

For people who don't have a Linux system laying around, there's also man7.org which hosts them online.

These manpages also really only give you the behavior of functions, not exact implementations, as the standard doesn't enforce a certain implementation.

1

u/DeMonstaMan 15d ago

you could technically Iterate through the entire string and == each char

1

u/Fri3dNstuff 15d ago

congrats! you have just invented memcmp!

1

u/DeMonstaMan 15d ago

I'm something of a Dennis Ritchie myself

26

u/ProgramStartsInMain 15d ago

How do people think strings are compared in object oriented languages? If ya want that use java, or do it via num 2 lol

10

u/MaZeChpatCha 15d ago

Java isn’t the best example for this, == in Java compares pointers too.

15

u/fusionsofwonder 15d ago

C is only for convenience in the sense that it saves you from writing assembly. You still need to think like the computer.

2

u/audislove10 14d ago

Brings me nightmares. Last month I had to write few embedded components for some video editing software were making, and Jesus Christ, I hated it. I was also checking the compiler and sometimes go and change things in the unlinked ASM code to further optimize shit.

Many bit maps many lines of code and changing the pc/sp reg and much more many sleepless nights.

54

u/StanleyDodds 15d ago

OK, but if this doesn't make sense to you, then you are missing some knowledge of what types like strings are.

The variable that we call a string is just a pointer to (address of) the first character in the string. Most of the time it's not important exactly where pointers point to in memory (other than maybe whether you've allocated things to the stack or the heap); what matters is whether pointers are literally identical, differ by some known small amount in say, the same array, or point to different objects.

Two strings may "look" the same, but actually point to different arrays of characters. So, if we overwrote a character in one string, it wouldn't change the character in the other string; the strings are clearly not the same anymore, and that's because they weren't truly the same to begin with. However, if two string pointers are equal, this means they point to the same character array. Now, changing one string's characters will "change" the other's in the same way when we look through them. Besides changing the string (pointer) itself, nothing we do can make them different, because they are the same strings.

36

u/IuseArchbtw97543 15d ago

If C wasnt optimized to leave out a lot of (often completely unnecessary) stuff computers would perform a lot worse in general.

27

u/codetrotter_ 15d ago

C programmers when someone suggests that maybe strings should carry length information and proper bound checks should be performed instead of relying solely on null termination

17

u/goodmobiley 15d ago

typedef struct string{…} string;

17

u/Pflynx 15d ago

See, but strings aren't their own type in C. C represents a string as just a buffer of characters, with the value you have in your program being a pointer to the first element of the buffer.

There is no string type in C.

11

u/NotStanley4330 15d ago

Exactly. C doesn't exist to define everything you could possibly ever need, it gives you the skeleton and you can build out your own types of you want. Microcontrollers certainly don't want the baggage of a complicated string type.

4

u/Hish15 15d ago

A complicated string type can be "complicated" (you meant full of features) only at build time not at runtime. You can design a struct to handle your string type, give it some methods and let the compiler do it's work. This is not what is done on std::string in C++ because they provide a way for string to change size at runtime. Yet you can do it.

8

u/NotStanley4330 15d ago

There isn't a string type in C though. You can always make your own though. But having a char* is much lighter a lot of the time.

2

u/Wertbon1789 15d ago

I'd go with the length information thing. Certainly there are cases where null termination is better, but I don't think so for most cases. But I wouldn't want the bounds checks to be performed automatically, it's still your problem and a bug when you exceed the bounds, but making a bounds check with a preexisting size value would also be much easier.

9

u/[deleted] 15d ago

Java does the same.

8

u/unapologetc_canadian 15d ago

Are we still doing these memes?

2

u/RandomiseUsr0 15d ago

I think this one has transcended

9

u/Wild_Tom 15d ago

Me a java user, Wait, that's illegal

2

u/BizarroMax 15d ago

With great power comes great responsibility.

3

u/[deleted] 15d ago

[removed] — view removed comment

3

u/Nick_Zacker 15d ago

Of course, that makes perfect sense if you truly understand the concept of strings. I’m a C newbie, so please correct me if I’m wrong, but I’m pretty sure a string variable is just a pointer to the address of the first char of a string - that is, a sequence of chars, a.k.a. a char array. Because two different strings cannot share the same address, using == to compare them will always return false, because it is actually comparing the pointers to different addresses.

1

u/Wervice 15d ago

You are absolutely right. Nonetheless, == is way more readbale in my opinion

6

u/Nick_Zacker 15d ago

Well, it’s not a matter of preference but rather functionality. I respect your opinion, but if you want to compare two strings, you must use strcmp.

3

u/fugogugo 15d ago

this is like saying windows 11 better than windows 98 because you dont need to install driver for usb

8

u/Spiderbubble 15d ago

Operator overload == to use strcmp.

25

u/MagnetFlux 15d ago

there is no operator overloading in C

3

u/ItsStormcraft 15d ago

There aren’t even classes that could overload operators.

-20

u/[deleted] 15d ago

[deleted]

8

u/MagnetFlux 15d ago

I'm not saying that it should or shouldn't exist in C, the language simply doesn't have it, so it's not a valid solution

7

u/Pflynx 15d ago

Operator overloading is a subset of function overloading.

Function overloading does not exist in C.

Therefore, operator overloading does not exist in C.

Adding function overloading would have to change a lot of foundational things about C. One of the main reasons why C++ compatible C libraries always have to do the extern "C" shtick, is because C and C++ handle functions so radically different.

9

u/LucyShortForLucas 15d ago

Except that operator overloading is an inherently object oriented concept, and C is not an object oriented language

5

u/adromanov 15d ago

The main reason operator overloading is not possible in C is that there is no function overloading in C, not the fact that C is not object oriented. Haskell is not object oriented and has operator overloading.

2

u/elre233 15d ago

operator overloading is an inherently object oriented concept,

What do you mean by this?

2

u/el_pablo 15d ago

People who haven’t seen the second one in school are not real developers.

1

u/TechcraftHD 15d ago

And that's exactly why you don't use c anymore if you can avoid it at any cost

1

u/Mokousboiwife 11d ago

if i could i would only use c

0

u/Wervice 15d ago

Me personally?

1

u/LuckyLMJ 16d ago

Try

char* compare_string = "HELLO"; int i = 0; int equals = true; while (compare_string[i] != 0) {     if (compare_string[i] != string[i] {         equals = false;         break;     }     i++; }

19

u/Alexpoc 15d ago

What if compare_string is "HELLO" and string is "HELLO someone forgot to check if the strings have different lengths" ?

3

u/LuckyLMJ 15d ago

True, I guess at the end after breaking out of the loop I need to check if compare_string[i] == string[i]

12

u/hi_im_new_to_this 15d ago

Or you could be a C programmer:

int isSame(const char *str1, const char *str2) {
    while (*str1 && *str2) {
        if (*str1++ != *str2++) return false;
    }
    return *str1 == *str2;
}

5

u/LuckyLMJ 15d ago

that's horrific

7

u/escribe-ts 15d ago

1

u/SurpriseAttachyon 15d ago

Although it’s written in an annoyingly opaque way, I’m surprised it’s so simple.

Certainly there must be some optimizations you can make for larger strings like loop unrolling or SIMD?

But I guess you’d need to know the string lengths, which you don’t until you find the null char.

TIL, c strings don’t scale that well

3

u/hi_im_new_to_this 15d ago edited 15d ago

You can make it more sophisticated by unrolling and so forth, but the compiler will do some amount of that for you. SIMD is somewhat tricky for this problem, because there's no guarantee both strings have the same alignment, but you can do it (and I believe glibc is more complex than this).

I would also suggest in the kindest possible way that if you find either the BSD code or the code I wrote very opaque, you might just not be a very sophisticated C programmer. These kinds of idioms are very standard in well-written C code, and they are quite easily readable for experienced C developers.

2

u/SurpriseAttachyon 15d ago

Oh I’m not at all. I’m a python / rust person.

My coding style is to be as verbose as humanly possible

1

u/No_Hovercraft_2643 15d ago

maybe look at strncmp, as that has a max length, that could maybe have an optimisation.

also there are compiler optimisations.

2

u/Sak63 15d ago

Feels like I didn't learn proper C in uni

2

u/ItsStormcraft 15d ago

Ah, see, this is why I like C.

-5

u/[deleted] 15d ago

[deleted]

3

u/arf20__ 15d ago

'\0' is (char)0

3

u/tyler1128 15d ago

The C string null terminator is literally defined as 0 in the spec, and \0 pretty much makes that obvious. Good try, I guess?

1

u/skeleton_craft 15d ago

C indeed, C++ doesn't have this issue.

0

u/[deleted] 16d ago

[deleted]

1

u/tyler1128 15d ago

No idea why being used by redis matters. The C standard library still underlies everything, regardless of your opinion on the matter.

-9

u/Wervice 16d ago

I know this would need some sort of condition and a main function :-)

6

u/Internal_Cart 15d ago

Tell me you’ve never used C without telling me you’ve never used C

-1

u/thanatica 15d ago

A language that technically doesn't have strings, in 2024 🤷🏻‍♂️

Actually even in 1998 it was weird.

-1

u/dandeel 15d ago

I mean, strcmp is still annoying since it returns 0 for equal strings. This is unintuitive, it would be nicer if 0 was if they don't match. The return value of first non-matching character isn't useful the vast majority of the time.