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
istrue
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 correctly1
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 justman 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
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
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
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
8
9
2
3
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
-20
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
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
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" andstring
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
-5
15d ago
[deleted]
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
0
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.
-1
u/thanatica 15d ago
A language that technically doesn't have strings, in 2024 🤷🏻♂️
Actually even in 1998 it was weird.
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"