views:

173

answers:

4

Hi there, the following code

#include <iostream>
using namespace std;

int main(){
    char greeting[50] = "goodmorning everyone";
    char *s1 = greeting;
    char *s2 = &greeting[7];

    bool test = s2-s1;

    cout << "s1 is: " << s1 << endl;
    cout << "s2 is: " << s2 << endl;
    if (test == true ){
        cout << "test is true and is: " << test << endl;
    }

    if (test == false){
        cout<< "test is false and is: " << test << endl;
    }

    return 0;
}

outputs:

s1 is: goodmorning everyone
s2 is: ning everyone
test is true and is: 1

here what does the line bool test = s2-s1; actually evaluate?, is it the length of the string?. If so, then seeing as s2 is a smaller than s1 it should be negative correct?, and yet the output is true?.

Also if i change it to bool test = s1-s2; I still end up with the same result. So it doesnt matter whether its negative or positive the it will be true? and only false when 0?.

what does the s2-s1 mean?

-cheers (trying to get rid of doubts:))

+7  A: 

If the result of the subtraction is zero, test will be false; otherwise it will be true.

Any value that is of a numeric type, enumeration type, or is a pointer can be converted to a boolean; if the value is zero (or null, for pointers), the result is false; otherwise the result is true.

James McNellis
ahk, also what does s2-s1 actually evaluate? length of the string?
sil3nt
@sil3nt: It returns the difference between the two pointers. `s1` and `s2` are just pointers. In this case `s2 - s1 = 7` because `s2` points to the seventh element of the char array and `s1` points to the zeroth element (the beginning) of the char array.
James McNellis
And just to clarify a little more, pointers are really integers underneath that hold an address (byte offset) to a memory location. So if you do pointer arithmetic, it's really doing arithmetic with the underlying memory addresses, which are numbers. The result is another pointer (integer), which is then implicitly converted to bool and assigned to `test`.
Cameron
@Cameron: Not entirely correct. Pointer arithmetic depends on the size in bytes of the datatype that the pointers point to. In the example above, we're using `char` which is 1 byte per element, hence you end up with 7. If we'd used `int` instead, the difference would have been 14, 28 or 56 depending on whether ints are 16, 32 or 64 bits on the architecture in use.
bluesmoon
@bluesmoon: Ah yes, you are right of course. Thanks for the correction.
Cameron
+1  A: 

C++ allows implicit conversions, so what it is doing is subtracting the pointer values of one array from another and if the result is null, then it is implicitly casting null to false. Anything else will be true, as bools work such that it's either zero (false) or true.

Thanks to Nathan S. and indiv for correcting me.

Caleb Thompson
Note that it does not subtract the characters in the strings, it subtracts the pointers as commented by @James McNellis .
Nathan S.
It certainly does not cast null to ascii zero, and ascii zero is not false, it's 0x30. Lots of misinformation here.
indiv
+5  A: 

Integer types, floating point types, and pointer types are all convertable to bool. For all of them, a value of 0 converts to false, and a non-zero value converts to true.

So, if s2 - s1 evaluates to 0, then test is false. Otherwise, test is true.

Since s1 and s2 are pointers, s2 - s1 is giving the difference between them (how far apart the addresses are). If they point to the same address, then the difference will be 0. If they point to different addresses, then the result will be non-zero. So, really all test indicates is whether s1 and s2 point to different addresses. s1 != s2 would give exactly the same result and would probably make more sense.

However, given that the values for s1 and s2 are hard-coded and are guaranteed to point to different addresses, the test doesn't really make any sense. It could make sense in another program though - particularly one where s1 and s2 are being passed into a function and you have no way of knowing ahead of time whether they're really the same.

Jonathan M Davis
If this test is being used to determine whether two pointers point to the same location, it'd be a lot more legible to just say `bool test = (s1 != s2);` :-)
Cameron
+2  A: 

The line bool test = s2-s1 does pointer subtraction, giving the number of chars separating s2 from s1. This result is then converted to a bool by converting to false if and only if the result is 0, otherwise converting to true.

For a detailed description of what's going on when you add/subtract pointers, see: http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/BitOp/pointer.html

Justin Ardini