0

The following program gives different results when compiled using gcc compiler, and turbo C

#include<stdio.h> 
#include<string.h>

void main()
{
    char* c = "gatecs2017";
    char* p = c;
    printf( "%d", (int)strlen( c + 2[p] - 6[p] - 1 ) );
}

Somebody please explain the working of the program. Also why it generates different results?

Dai
  • 141,631
  • 28
  • 261
  • 374
Sharon
  • 171
  • 1
  • 13
  • 1
    Could you also provide the outputs, please? – Gnqz Feb 14 '17 at 08:52
  • 0 in turbo C and 1 in gcc. Also I got 23 when run in codeBlocks – Sharon Feb 14 '17 at 08:54
  • Turbo C hasn't been updated since 1988 - do you mean Turbo C++ instead? – Dai Feb 14 '17 at 08:54
  • Ideone printed `0` (after I fixed `main()` to return `int`, of course). Kind of surprised it didn't hit me over the head. This is some messed up code. – unwind Feb 14 '17 at 08:54
  • 4
    Do you know what e.g. `2[p]` does? Do you know anything about pointer arithmetic? What is the result of `c + 2[p]`? What is the result of `c + 2[p] - 6[p]`? What is the result of `c + 2[p] - 6[p] - 1`? Is that result a valid pointer to a valid and terminated string? – Some programmer dude Feb 14 '17 at 08:54
  • 3
    It's undefined behaviour. – Jabberwocky Feb 14 '17 at 08:55
  • given ASCII, `2[p]-6[p]-1` equals 65, so you are reading outside of the string. eg Undefined Behaviour. – sp2danny Feb 14 '17 at 08:57
  • Perhaps the two compilers have different signedness of `char`, leading to different results in the scary arithmetic. Or perhaps gcc detects the UB and does something completely different. You should disassemble the code, but the answer really is "it doesn't matter, UB". – unwind Feb 14 '17 at 08:57
  • Very similar to [What do `2[p]` and `6[p]` mean?](http://stackoverflow.com/questions/42179769/what-do-2p-and-6p-mean) except the string there is `"GATECSIT2017"` which has defined behaviour whereas with the string `"gatecs2017"`, the behaviour is undefined because of the missing `"it"`. – Jonathan Leffler Feb 14 '17 at 17:00

2 Answers2

4

strlen(c+2[p]-6[p]-1) is translated to strlen(((c + 't') - '2') - 1) = strlen(((c + 116) - 50) - 1), thus, accessing outside of the bounds of the string (undefined behaviour).

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Excuse me if I am asking a blunder. What is the meaning of c+116? – Sharon Feb 14 '17 at 10:17
  • @elantra: its pointer arithmetic, an example :`char *str = "maria" + 2;` gives you `"ria"`, this example is valid but yours is not (because you exceed the len of the string, as `char *str = "maria" + 116;`) – David Ranieri Feb 14 '17 at 10:20
0

As clearly explained by others, c + 2[p] - 6[p] - 1 is past the array bounds.

Where exactly, and why different results, here's the redundant explanation that hasn't been given yet:

c+116 is an address on your stack that's address of c + 116 bytes. Then call strlen(address) and you'll get the length of the area starting from c+116 on your stack until there's a '\0'. Since that area is uninitialized or is set differently by different compilers since it's likely somewhere in your executable when loaded to the memory by the kernel running your executable (assuming a kernel ran it), you'll get different results with each compiler-output executable.

AlbusMPiroglu
  • 645
  • 3
  • 13