0
#include <stdio.h>

void fun(int *a, int *b) {
    //printf("%d %d\n", a[2], *b);
    ++b; a[2] = a[1] + 6;
    return;
}

int main(void) {
    char A[5] = {'0', '1', '7', '3', '4'};
    fun(A, A[2]);
    printf("%c", A[2]);
}

I read here char to integer pointer conversion that accessing a char array using int* is undefined behaviour. Is this program similar to the one in that link?

Also, I want to know why I get a runtime error, if I uncomment the first statement in the funciton fun

VillageTech
  • 1,968
  • 8
  • 18
Stupid Man
  • 885
  • 2
  • 14
  • 31
  • 1
    Are you asking whether giving very much other typed values to a function than prototyped is UB or anything other of your weird code? The first value you give can be seen as a pointer to char, not int. The second is even further from being a pointer to int, it is a char. – Yunnosch Dec 09 '19 at 07:33
  • 2
    You pass a single `char` value as the second argument, and the function expects a pointer to an `int`. Listen to your compiler, it will warn about these things. And if not, then enable more warnings (using e.g. `gcc` or `clang` add at least the `-Wall` flag). – Some programmer dude Dec 09 '19 at 07:34
  • 1
    This is a constraint violation , the arguments to `fun` are both incompatible with the parameters. You must get a compiler diagnostic from a conforming compiler, and any behaviour is undefined – M.M Dec 09 '19 at 07:36
  • @DavidC.Rankin No, because the value of `a` is not `A`, it's `(int*)A`. – aschepler Dec 09 '19 at 07:58

1 Answers1

4

This is UB in 5 different ways:

  • It is UB because it does not compile. You aren't accessing a character array through an int*, you are trying to convert a single character into a int*, which isn't valid C. See "Pointer from integer/integer from pointer without a cast" issues

  • Similarly, you cannot implicitly convert from a character array to an integer pointer. You need an explicit cast for that.

Fixing the code so that it compiles, fun((int*)A, (int*)&A[2]);, then in the function:

  • a[2] could lead to a misaligned access on many systems, which would be UB.

  • a[2] is likely an array out of bounds access, given that int is 32 bits. UB.

  • a[2] = a[1] + 6; does a lvalue access of the array through a non-compatible type. This is a "strict aliasing violation" and also UB. What is the strict aliasing rule?

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thanks for your response. When you say the code doesnt compile, you meant without any warnings? https://ideone.com/ky7E6L – Stupid Man Dec 09 '19 at 08:20
  • 1
    @StupidMan Several compilers like gcc have lax default settings. There is nothing in the C standard called "compiler errors/warnings", it only speaks of diagnostic messages. Therefore a compiler can get away with just giving you a warning even though your code isn't valid C. To get errors for C language violations on gcc or clang, use `-std=c11 -pedantic-errors`. – Lundin Dec 09 '19 at 08:35
  • Not compiling is not a guaranteed symptom of undefined behaviour. In fact, undefined behaviour is not required to be diagnosed at all. Some compilers may be able (if appropriately configured) to diagnose some instances of undefined behaviour, but the standard doesn't require that. Using casts (explicit type conversions) to force code to compile allows undefined behaviour to occur (often subsequently). – Peter Dec 09 '19 at 12:51