bool colon initialization - c++

While reading some C++ code, I saw and was confused by this little line in a class:
bool x:1;
In debug builds, I noticed that 'x' is initialized as 'false', but I can not find any documentation about that. Can anyone tell me what this syntax does?

it's a bit field. read up on bit fields in your c++ textbook.
the initialization to false is independent of the declaration. whether it is guaranteed by your code depends on your code (not given).
the c++ standard gives the compiler some leeway for integer and enumeration bitfields of size 1: storing the value 1 in such a field, you may get out the value -1. happily this applies only to fields of size 1, and it does not apply to a field of type bool.

Related

Understanding enum's types in Crystal

I am trying to implement the famous Lox language based on Robert Nystrom's book, but in Crystal. Now I stumbled upon the following flaw/error:
I have an enum for OpCodes, with type UInt8:
enum OpCode : UInt8
OP_RETURN = 1
end
and an array of UInt8's
#code = Pointer(UInt8).malloc( 8 )
But now when I want to assign code[0] = OP_RETURN, even with all possible type conversions I still get the following error message:
Error: can't cast OpCode to UInt8
But I thought OpCode WAS UInt8 as declared.
Any ideas? Really appreciated. I'm just in the baby steps of learning Crystal but so far I'm impressed by this language but there are edge corners where one just needs help.
Crystal's enums provide a type safe way to define a list of related magic values. They're not meant to be interchangeable with their underlying value.
Your options are to base your array on the type directly and if really needed to convert on use of the values from the array. Or to convert the enum to the underlying value when assigning to the array. In either case you would do this simply by calling #value on the enum value instance, OpCode::OP_RETURN.value. But I would recommend to try to stay high-level and keep working with the enum instance values directly for as long as possible. Rest assured there's no performance penalty when doing so.
Read more about enums in the language reference: https://crystal-lang.org/reference/1.4/syntax_and_semantics/enum.html
On a side note I can only recommend you strongly to not abuse Pointer as an "array", use the dedicated Array class, Slice if you really need to go lower level or StaticArray when you need value semantics. All of these provide #to_unsafe for use cases where you need to provide a Pointer to a third party library that expects it.

Bool member variable in class is set to True when uninitialized

Updates:
The reason I was getting true is because anything that is other than 0 would be considered true which obviously makes sense to how unlikely it would have been for me to get false when uninitialized.
I have read a post similar to my question on StackOverflow, it talked about that it is good practise to initialize all member variables, which I agree with.
Post: Boolean variables aren't always false by default?
This post is a bit old (9 years ago) so I just think maybe somethings might have been changed in the new C++ versions, I am currently using C++17. I also have one slight different question from the ones talked about in the post.
I am aware that if a variable is uninitialized it may contain some "garbage data" or as one of the answers in the post said (which I think that is what they meant but I'm not 100% sure), "if not explicitly initialized -- will contain an arbitrary value.".
I have tried testing that, and the results showed that when I didn't initialize my variables, they contained random numbers (for int, double). I also tested std::string but they are set to "" by default from what I saw.
Anyways, now when I tried for the built in type bool I would always get true (after class is constructed, but again that boolean value never initialized, I would go into debug and see that the value would be true), what I am confused is that no matter how many times I tried to test if that was just a random value out of true and false, and if sometimes it would be false, it was always set to true. If uninitialized shouldn't the value be "random" kind of? Why did it always set to true (again when a member variable of my class which wasn't initialized on construction).
Solutions I tried:
Obviously one is just to initialize on construction, but I thought of another one...
What if on construction I wanted it to be true and not false but when it hasn't been constructed to be set to false then that way when I have a vector of pointers to my object I can check that I am not reading uninitialized objects when following the pointer by checking whether that boolean is set to true (if initialized) or false otherwise. I wouldn't be able to use method 1 which was to initialize on construction to false, also because if we are reversing the behaviour I can't rely on what that uninitialized boolean member variable would be as I mentioned in the above paragraphs I am unsure what behaviour that has due to the results I had been getting. I did the following and it worked...
class Testing{
private:
bool condition{false} // Initalize it here which kind of makes me confused but it works
public:
Testing() : condition{true} {} // Constructor setting the condition value to true
};
Could someone explain if it is wrong to do this, personally I have never seen someone do this but I tried it and no errors were given.
While bool conceptually contains only one bit of information, the requirements of the C++ standard mean that a bool object must take up at least eight bits. There's three main ways that a compiler might represent bool at a bitwise level:
All bits zeroed for false; all bits one'd for true (0x00 versus 0xFF)
All bits zeroed for false; the lowest bit one'd for true (0x00 versus 0x01)
All bits zeroed for false; at least one bit one'd for true(0x00 versus anything else)
(Note that this choice of representation is not ordinarily visible in the effects of a program. Regardless of how the bits are represented, a bool becomes a 0 or 1 when casted to a wider integer type. It's only relevant to the machine code being generated.)
In practice, modern x86/x64 compilers go with option 2. There are instructions which make this straightforward, it makes casting bool to int trivial, and comparing bools works without additional effort.
A side effect is that if the bits making up a bool end up set to, say, 0x37, weird stuff can happen, because the executable code isn't expecting that. For instance, both branches of an if-statement might be taken. A good debugger should loudly yell at you when it sees a bool with an unexpected bit pattern, but in practice they tend to show the value as true.
The common theme of all those options is that most random bit patterns are not the bit pattern for false. So if the allocator really did set it to a "random" value, it almost certainly would be shown as true in the debugger.

Can a variable become null by left or right shift operation in c / c++?

i have a code snippet in which i assign a value to a variable , var. In between the variable is acted upon left/right shift operations. Can such a variable ever become null.
Note that null is mostly defined as
#define null ((void*)0)
If it can't be null, then a check like:
if (var == null)
will give rise to dead code which will never be executed.
Built-in shift operators are only applicable to values of integral or unscoped enum types. Built-in comparison to your null is only legal for values of pointer types. This means that results of built-in shift can never be compared to your null. (The only potential loophole here is the possibility to use shifts to form a null-pointer constant - an integral zero. But this is only possible in pre-C++11 version of the language. Not anymore.) The comparison is invalid.
In other words, there's no valid context in which this question can even arise. Your if will not produce "dead code" or "alive code". It simply won't compile at all.
But if you are talking about overloaded operators, then everything is possible. However, in that case your question is too broad to make sense.
In C, you can compare interger values to pointers, so that code would produce a warning but probably work as expected. (Definitely not recommended, though)

how casting of return value of main() function works?

I am using Visual studio 2008.
For below code
double main()
{
}
I get error:
error C3874: return type of 'main'
should be 'int' instead of 'double'
But if i use below code
char main()
{
}
No errors.
After running and exiting the output window displays
The program '[5856] test2.exe: Native'
has exited with code -858993664
(0xcccccc00).
Question: Is compiler doing implicit cast from default return value of zero(integer) to char ?
how the code 0xcccccc00 got generated ?
Looks like last byte in that code seem to be the actual returned value. Why 0xcccccc is coming ?
The correct way to do it, per the C++ standard is:
int main()
{
...
}
Don't change the return type to anything else or your code will not be C++ and you're just playing with compiler specific functionality. Those ccccc values in your example are just unitialized bytes (which the C allocator sets to 0xCC) being returned.
The value returned from the main function becomes the exit status of the process, though the C standard only ascribes specific meaning to two values: EXIT_SUCCESS (traditionally zero) and EXIT_FAILURE. The meaning of other possible return values is implementation-defined. However there is no standard for how non-zero codes are interpreted.
You may refer to an useful post:
What should main() return in C and C++?
Yet another MSVC extension/bug!
The answer to your first question is sort of yes. A char is essentially a very small integral type, so the compiler is being (extremely) lenient. Double isn't acceptable because it's not an integral type. The 0xCCCCCC is memory that never got initialized (except for the purposes of debugging). Since ASCII characters can only have two hex digits, the conversion failed to set the first 24 bits at all (and just set the last 8 bits to 0). What an odd and undesirable compiler trick.
About main function, $3.6.1/2 - "It
shall have a return type of type int,
but otherwise its type is
implementation-defined."
As I understand, anything that mentions 'shall' in the standard document AND is not ahdered to by the code is an instant condition required to be diagnosed by the compiler, unless the Standard specifically says that such diagnosis is not required.
So I guess VS has a bug if it allows such a code.
The main function is supposed to return an int. Not doing that means you're out in undefined territory. Don't forget to wave at the standard on your way past. Your char return probably works because char can be easily converted to an int. Doubles can certainly not. Not only are they longer (double the length) but they're floating point, which means you'll have 1s in wonky places.
Short answer: don't do that.
It is probably because char will implicitly cast to an int, however double won't as there would be data loss.
(See here: http://msdn.microsoft.com/en-us/library/y5b434w4%28v=VS.71%29.aspx for more info)
However you don't see the conversion problem because the compiler catches the worst sin (as stated in the other answers) of using a non standard return type.

Simple C++ syntax question about colon

I just saw a code snippet with a piece of syntax that I have never seen before.
What does bool start : 1; mean? I found it inside a class definition in a header file.
struct record {
char *name;
int refcount : 4;
unsigned dirty : 1;
};
Those are bit-fields; the number gives the exact size of the field, in bits. (See any complete book on C for the details.) Bit-fields can be used to save space in structures having several binary flags or other small fields, and they can also be used in an attempt to conform to externally-imposed storage layouts. (Their success at the latter task is mitigated by the fact that bit-fields are assigned left-to-right on some machines and right-to-left on others).
Note that the colon notation for specifying the size of a field in bits is only valid in structures (and in unions); you cannot use this mechanism to specify the size of arbitrary variables.
References: K&R1 Sec. 6.7 pp. 136-8
K&R2 Sec. 6.9 pp. 149-50
ISO Sec. 6.5.2.1
H&S Sec. 5.6.5 pp. 136-8
it's a bitfield. : 1 means one bit is used.
see for example http://msdn.microsoft.com/en-us/library/ewwyfdbe(VS.71).aspx
It means that start is 1 bit wide, as opposed to the normal bool which is 1 byte long. You can pack multiple smaller variables into a larger variable and the compiler will generate all the and/or code necessary to read/write it for you. You will take a (noticeable) performance hit, but, if used right, you'll use a lot less memory.
See the Wikipedia entry about Bit Fields. It tells the compiler how many bits the structure member should occupy.
It makes the member start into a bit-field, with 1 bit of space reserved.
It's only valid for struct/class members, you can't have a bit-field variable.
This is the syntax for bit fields
Essentially, you define a field in a struct to have only a few bits of a full byte or short or int.
Several bit fields may share the same int so this method can be used as a clever way to avoid some bit manipulations in constructing values.
This is the syntax for describing bit fields. This is a way of packing more information into a smaller amount of storage. Whereas normally a bool would take at least a byte (probably more) to represent, by using bit fields, you can combine several bools into one byte with a simple syntax.
Be careful though. As one of lesser-known areas of the language, you may run into corner cases when using them. For example, the data structures thus produced are probably not portable between processor types.
It's a bit-field. But I've never tried making bit-fields on boolean.