Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Cast uninitialized variable to (void)

Parent

Cast uninitialized variable to (void)

+3
−0

Is it undefined behaviour to cast an uninitialized variable to (void)?

Example:

int main()
{
  int x;
  (void)x;
  return 0;
}
History
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

2 comment threads

What are you trying to achieve? (3 comments)
I wonder if I should also tag this C++ also. The answer *might* be different for these different lang... (3 comments)
Post
+0
−0

Well, an "uninitialized" variable is, in fact, not uninitialized as that terminology may suggest; it is just filled with random garbage that happened to be on that memory section. That is to say, uninitialized variables are not special, they just happen to not contain any meaningful value, but they do have a value.

void is not a type, rather the contrary -- it's the absence of type. Knowing this, casting to it wouldn't make much sense but as it happens, it is allowed; it simply discards the expression being cast.¹²

Now, casting to a void pointer (void*) is another thing. It's mostly used as a sort of "generics" in C (e.g, the standard qsort function uses this). Since these pointers are aligned as character ones³ and can be cast to any other pointer type, you can write functions that take void pointers but cast them to their concrete types inside, thus allowing a generic-like function signature (naturally, a whole lot less safe than what you may find in other languages).

Null pointers are essentially void pointers to an integer constant expression of value 0 and have the interesting property of being guaranteed that when cast to concrete pointer types, they will never be considered equal.⁴

Hope this answers your question, if not let me know in the comments :)


¹ From C's standard, section 6.3.2.2:

If an expression of any other type is evaluated as a void expression, its value or designator is discarded. (A void expression is evaluated for its side effects.)

² From C++'s standard, section 5.2.9.4:

Any expression can be explicitly converted to type cv void." The expression value is discarded.

³ From C's standard, section 6.3.2.3:

A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

And 6.2.5.27:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.

⁴ From C's standard, section 6.3.2.3:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Don't confuse common implementations with the specification (3 comments)
Don't confuse common implementations with the specification
Derek Elkins‭ wrote over 1 year ago

While it's not uncommon to simply (stack) allocate space for local variables, so that their value is based on whatever was in that space on the stack, this is not specified by the standard. Talking about implementation details like this is often misleading for C (and C++). The standard allows a much broader set of implementations than the "typical" ones. This means code that would seem reasonable relative to the "typical" implementation often evokes undefined behavior. For example, nothing in your answer suggests that it would be undefined behavior to simply use an uninitialized variable as normal.

Currently, your answer starts with a misleading and untrue statement based on implementation details; makes one reference to the C standard that is partially relevant but not enough to resolve the question; then the remainder, which is the bulk of the answer, talks about something that was not asked. Estela's answer provides a much better example of how to address this type of question.

Lundin‭ wrote over 1 year ago

Derek Elkins‭ For the most part it is fine to use such a variable, as in it won't cause you program to crash and burn (not undefined behavior), but it will not produce anything meaningful or deterministic either (it is unspecified behavior). With the exception of trap representations, which are mostly irrelevant to discuss in the context of 2's complement integers. There's another rule which could make accessing a local variable UB however, I posted an answer about that.

Derek Elkins‭ wrote over 1 year ago

@Lundin "For the most part" is not the same as "always". There can be (and likely are) implementations where this is not the case, such as the executable specification in the K Framework explicitly designed to catch undefined behavior. As in your answer, the spirit of the question seems more general than the particular example given, i.e. it's not specifically about int variables. Regardless, my main point with the comment was that talking about implementation details is simply not an appropriate way to address this type of question.