16

I found this in c99 standard

3.17.2
1 indeterminate value
either an unspecified value or a trap representation

This above statement is not clear to me. Can anyone explain what is this and what are its pros and cons?

Some example will be highly appreciated.

Ry-
  • 218,210
  • 55
  • 464
  • 476
Omkant
  • 9,018
  • 8
  • 39
  • 59
  • 1
    I'm also interested in it's usage of a "trap representation", what's that supposed to mean as well? – enjoylife Nov 16 '12 at 20:11
  • 2
    A good example of a trap representation are signalling NaNs. Some processors will issue an exception when a signalling NaN is encountered. An indeterminate value can be a signalling NaN. – Mysticial Nov 16 '12 at 20:12
  • 3
    The discussion would not be complete without a reference to Defect Report 322: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1208.htm – Pascal Cuoq Nov 16 '12 at 20:17
  • 2
    A signaling NAN is not a trap representation. It's a valid floating point value. Trap representations essentially don't exist in the real world; the canonical examples would be implementations with parity/checksum in the padding bits (in which case, bad parity/checksum would be a trap representation) and "negative zero" on sign/magnitude and ones-complement systems that don't support a negative zero. – R.. GitHub STOP HELPING ICE Nov 16 '12 at 20:31
  • @PascalCuoq: is there a response to that defect report? The reporter has read the text the same way I did, and reacted to that reading in horror (as not representing the intention of the committee) the same way you did. – Steve Jessop Nov 17 '12 at 02:10
  • 3
    @SteveJessop Yes, I should have provided this link instead: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_338.htm Without it, we wouldn't have the notion of “object of automatic storage duration that could have been declared with register storage class” in C11. DR260 is also good reading: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_260.htm – Pascal Cuoq Nov 17 '12 at 11:21

2 Answers2

16

The differentiation of the two (indeterminate values and trap representations) is fundamental. In one case you have no known value. In the other you have a known-invalid value.

Simplest example of an indeterminate value I can muster:

int a;
int b = a;

There is no concept of determinate 'value' associated with a. It has something (as it is occupying memory) but the "what" it has is not defined, thus indeterminate. Overall, the concept is as simple as it sounds: Unless it has been decided what something is, it cannot be used in any evaluation (think r-value if it helps) with deterministic results.

The actual value depends on the language, compiler, and memory management policies. For instance, in most implementations of C, an uninitialized scope variable or the memory pointed to by the pointer returned by a call to malloc will contain whatever value happened to be stored at that address previously. On the other hand, most scripting languages will initialize variables to some default value (0, "", etc).

Regarding Trap Representation, it is essentially any value that is outside the restricted domain of the allowable values pertaining to the underlying formal definition. A hopefully non-confusing example follows. :

enum FooBar { foo=0, bar=1 };
enum FooBar fb = (enum FooBar)2;

In general it is any bit pattern that falls within the space allowed by the underlying storage representation (in enums that is likely an int) but is NOT considered a valid "value" for the restricted domain of its formal definition. An outstanding description on trap representations and their roots can be found at this answer. The above is just a representative of what a very simple known-invalid representation may appear as. In reality it is practiced in hardware for detection of values that trigger invalid-state. I think of them as "panic" values. Again, the above code is solely idealistic in demonstrating the concept of a "value" this is not "valid", but is, in fact, known.

Community
  • 1
  • 1
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • It means can we say it garbage value ? – Omkant Nov 16 '12 at 20:12
  • We can say we don't have a clue what *it* is. – WhozCraig Nov 16 '12 at 20:13
  • @WhozCraig: one more thing,give answer about trap representation.. I haven't read anything about trap in `C ` – Omkant Nov 16 '12 at 20:14
  • @Omkant amended for discussion of trap-representation. I hope it makes sense. – WhozCraig Nov 16 '12 at 20:46
  • one more thing that i didn't ask in the question , `Is accessing indeterminate value or trap representation causes Undefined behaviour or unspecified behaviour`? – Omkant Nov 16 '12 at 20:55
  • got confused by reading that outstanding description http://stackoverflow.com/questions/6725809/trap-representation – Omkant Nov 16 '12 at 20:59
  • @Omkant In the case of indeterminate values, most definitely it is undefined. Another example is dereferencing an uninitialized pointer. In the case of trap-representations, it is gray to me, as the value is *defined* but is known-invalid. Ultimately I believe the distinction is made to allow a trap *condition* to happen *because* of trap-representation *detection*. I hope that made sense. – WhozCraig Nov 16 '12 at 21:03
  • @Omkant Try not to read the whole thing post of that link; just the first part of the accepted answer. – WhozCraig Nov 16 '12 at 21:04
  • 4
    It's implementation-defined whether or not `int` *has* any trap representations. If it doesn't (and I've never actually used an implementation that did have trap values of `int`), then it is not undefined behavior to read an indeterminate value: you know that it's not a trap value, so it's a valid value of the type `int`, it's just unspecified which one. In C++, by contrast, it's explicitly UB to read any uninitialized value. In both C and C++ it's UB to read a trap representation. – Steve Jessop Nov 16 '12 at 21:54
  • 1
    @SteveJessop It is clearly the intention of the committee that even if `int` does not have trap values, it is undefined behavior to read from an indeterminate lvalue of type `int`, as witnessed by the non-normative annex J. The compilation choices described in http://kqueue.org/blog/2012/06/25/more-randomness-or-less/ show that some compiler makers also choose the “undefined behavior” interpretation. – Pascal Cuoq Nov 16 '12 at 23:12
  • 1
    @Pascal: fair enough, "The value of an object with automatic storage duration is used while it is indeterminate" certainly doesn't say "only if the type has trap representations". Shame that the committee wasn't able to frame normative text to that effect (or maybe they did and it's a shame I wasn't able to find it). – Steve Jessop Nov 17 '12 at 01:13
  • 1
    @SteveJessop It matters to me in my job, and I hate how varying interpretations come from all sides. Programmers think they should be allowed to write their own `memcpy()`: fair enough, but next they want their `memcpy()` to work on indeterminate data, too. Some academic claims that one can apply `f()` to an indeterminate value if `f()` does not use its argument: again, fair enough, the standard does not explicitly say that an lvalue is “used” when it is passed as argument. I really, really hope the next C standard will be executable. – Pascal Cuoq Nov 17 '12 at 01:38
  • @Pascal: yes, there are plenty of areas of uncertainty and I didn't mean to add another. Re: `memcpy` I guess it's down to whether an object within its lifetime "holds" its indeterminate value. If so, its bytes should be accessible, right? The function argument issue I actually don't get why it's in doubt: isn't the argument sub-expression evaluated prior to even calling the function, and doesn't evaluating an lvalue read its value in C? Does the same academic say a volatile lvalue argument is accessed if and only if it's used in the function? But I take your word that it's a thorny issue :-) – Steve Jessop Nov 17 '12 at 01:45
  • @SteveJessop as far as I understand [prior to the latest C++ draft standard](http://stackoverflow.com/questions/23415661/has-c-standard-changed-with-respect-to-the-use-of-indeterminate-values-and-und) we had to rely on the lvale-to-rvalue conversion to get undefined behavior when using an indeterminate value but since it is [underspecified](http://stackoverflow.com/questions/14991219/what-is-the-value-category-of-the-operands-of-c-operators-when-unspecified) so is the UB when using an indeterminate val. I only ask since [this answer](http://stackoverflow.com/a/23831247/1708801) quotes. – Shafik Yaghmour May 30 '14 at 13:27
  • @PascalCuoq: If an optimization would be beneficial for some programs but others programs would benefit from behavioral guarantees which the optimization would violate, that would suggest that regardless of whether the standard would "allow" the optimization, there should be a option to enable the optimization for the programs which benefit (bearing in mind that conforming compilers can support non-conforming options), but there should also be an option to disable the optimization and uphold the sometimes-useful guarantees, whether or not the Standard would require such an option. – supercat Feb 20 '17 at 23:01
  • I'm not sure what the enum example is about, `enum FooBar fb = (enum FooBar)2;` is valid and not a trap representation. `printf("%d\n", (int)fb);` must print `2`. – M.M Jul 16 '19 at 02:50
5

Unless otherwise specified, static objects contain zero or null pointer values upon program startup. Automatically and dynamically allocated objects are initialized only if an initial value is explicitly specified; otherwise they initially have indeterminate values (typically, whatever bit pattern happens to be present in the storage, which might not even represent a valid value for that type).

Reference : WikiPedia

aleroot
  • 71,077
  • 30
  • 176
  • 213
  • @Omkant generally you can assume that an indeterminate value means the value is whatever happened to be in the storage your variable is now using. – Ethan Reesor Jun 30 '13 at 21:28
  • @omkant No, you are using a much looser definition of "garbage" than the rest of us. Garbage means "invalid". With indeterminate, the value may actually be non-garbage in the context you wanted it, the behavior is thus undefined. Consider: `char g[] = {"Hello", "Hi", "Howdy"}; int n; printf("%s\n", g[n]);`. There is a very small change that this will not crash. But consider this: `char g[] = {"Hello", "Hi", "Howdy"}; {int i = 1;} {int n; printf("%s\n", g[n])};`. This has a high probability of outputting "Hi", but not guaranteed (compiler, os, options, etc depending) – kfsone Jun 30 '13 at 21:57