-1
    scanf("%f", &lista2.pret);
    fflush(stdin);

    if (lista2.pret == NULL ) goto eror2; // error

    fseek(o,(nn-1)*sizeof(lista2),SEEK_SET);
    fwrite(&lista2,sizeof(lista2),1,o);

    break;
  }

  fclose(o);
  break;
}

Error:

[Error] invalid operands to binary == (have 'float' and 'void *')`

What is wrong?

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 1
    A `float` can never be `NULL`. This is an invalid comparison. – Code-Apprentice Jun 17 '18 at 11:40
  • 1
    `lista2.pret == NULL` is invalid, that's what's wrong. What are you trying to do there? – melpomene Jun 17 '18 at 11:42
  • How is `pret` defined? – alk Jun 17 '18 at 11:43
  • 1
    Which compiler are you using? – alk Jun 17 '18 at 11:44
  • @Code-Apprentice: A `float` can compare equal to `NULL`. Per the C standard, `NULL` is a *null pointer constant*, and a null pointer constant is either an integer constant expression with value 0 or such an expression cast to `void *`. If a C implementation chooses the former, then `lista2.pret == NULL` is a valid expression, in which the integer zero will be converted to `float`. So there are more concepts at play than merely ”`NULL` is not for `float`.” – Eric Postpischil Jun 17 '18 at 14:34
  • @melpomene: Whether `lista2.pret == NULL` is invalid is implementation-dependent, per my comment above. – Eric Postpischil Jun 17 '18 at 14:34
  • @EricPostpischil I'd argue that it's always semantically nonsense (because `NULL` is meant for pointers). However, we also know that it's invalid on the implementation OP uses because the error message says so. – melpomene Jun 17 '18 at 14:36
  • @melpomene: Yes, it is always an error in practice. But you cannot expect learners to have the background knowledge to know that. When teaching, (a) things that experts assume have to be stated explicitly, and (b) the statements teachers make ought to be actually true. Stating that `lista2.pret == NULL` is invalid because it is wrong in our heads (but not always truly invalid in the compiler-accepted-source-code sense) can actually mislead people who do not have the same context in their heads and may go on with wrong information in their heads that later leads to wrong conclusions. – Eric Postpischil Jun 17 '18 at 14:38

2 Answers2

2

There is a constraint on the == operator such that:

— both operands have arithmetic type;

— both operands are pointers to qualified or unqualified versions of compatible types;

— one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void; or

— one operand is a pointer and the other is a null pointer constant.

lista2.pret is obviously a floating point (arithmetic) type, so it cannot be compared to NULL. Only pointer types can be compared to NULL.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • This answers technically. However, if we look at the code, why would somebody compare a `float` to `NULL`? To people knowledgeable in C, that makes no sense, because they are different and are intended to be disparate. The fact that it is just after a `scanf` is a clue. The author appears to be attempting to discern whether a `float` was successfully obtained. This makes sense in some programming languages; some other programming languages have *null* placeholders to indicate a value is not present. Thus, the true question the OP is asking may be: “Why didn’t my test for scanf success work?” – Eric Postpischil Jun 17 '18 at 14:54
0

To test whether scanf successfully scanned a float in this situation, you should use:

if (1 != scanf("%f", &lista2.pret))
    goto ero2;

The float type does not use NULL to indicate there is no value. NULL is used with pointers that way—a pointer can have either the address of an actual object or can have the “value” NULL. However, unlike some other languages, C does not generally have a null value that indicates an object is not holding a valid value. NULL is intended for use just with pointers, not with integers, floating-point values, or other types of objects.

The floating-point type actually does have a “value” to indicate the object is not holding a number. It is called a NaN, for Not a Number, and is NAN in source code after including <math.h>. You could test whether lista2.pret is a NaN. However, since NaNs are not numbers, they cannot be equal to anything, so you would not test with lista2.pret == NAN. Instead, you would use isnan(lista2.pret).

However, scanf does not indicate failure by putting a NaN in a float. scanf indicates failure by its return value. It returns the number of conversions it successfully performed. So, when using scanf(%f, &lista2.pret) to convert some input to a float, the result will be 0 or 1 to indicate 0 or 1 successful conversions. It may also be EOF to indicate some input failure occurred. So, to test whether scanf successfully scanned a float, compare its return value to 1.

(Incidentally, you should know that fflush(stdin) is an extension to the base C language that is implementation dependent. You are likely using Microsoft Windows. On other C implementations, fflush(stdin) may not work the same way and could break your program.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312