Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using (+ve integer) + "some string " in printf? [duplicate]

#include <stdio.h>

void main() {
    printf(2 + "abcdefgh");
}

How does this code print cdefgh? Compiler throws an error if I use 2- or 2* or any other operator.

like image 955
Karthik Bhat Avatar asked Jun 13 '26 21:06

Karthik Bhat


2 Answers

When using string literals such as "abcdefgh" you actually have a pointer to a section on memory where this string resides. Basically you pass to printf a pointer to that location and instructs it to move the pointer 2 locations ahead, resulting in the a string starting from the 3rd char instead of the first

Note that you can use - but you need to use it like you do pointers arithmetic, like

printf("abcdefgh" - 0); // using -N where N >0 would be UB

So, this code is valid

int main()
{
    printf("abc\n" - 0);
    printf(1+"def");
    return 0;
}

but using *,/ will not (also bitwise operators |,& will not be valid)

like image 148
CIsForCookies Avatar answered Jun 16 '26 10:06

CIsForCookies


In this code

printf(2 + "abcdefgh");

is the same as

printf(&("abcdefgh"[2]));

where, the argument serves as the format string in the printf().

To elaborate, from the properties of string literals, quoting C11, chapter §6.4.5/P6

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence. [...]

and for an array, from chapter §6.3.2.1,

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [...]

so, in case of the function call argument, as one of the arguments of addition operator, the string literal actually bols down to the address of the first element in the literal, and then, the addition, which is a pointer arithmetic, takes place. The result is in incremented pointer which points to the third element (C arrays are 0-based index).

That said, as emphasized in previous paragraph, a pointer arithmetic is only valid for additive operations, not Multiplicative operators.

like image 37
Sourav Ghosh Avatar answered Jun 16 '26 12:06

Sourav Ghosh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!