Solved

A bit type that is actually only one bit in size and not 8 or 16 or 32?

Posted on 2002-07-26
31
205 Views
Last Modified: 2010-04-01
Here's another one for you out there that just mught happen to know how to do this.  I want to be able to create any size type that I want, like in ADA you can set a range for a new type so you can actually create a one bit type to whatever (probably only 64bits, I don't know).  I would like to be able to do this in C++ and have a feeling that it will require a bit of assembler to do it with.  I'm a bit rusty in that department.  I'm just not sure where to actually begin.  Does anyone have any comments on this.  I have a feeling that you can't and I'm hoping I'm wrong.    
0
Comment
Question by:MacLeod
  • 17
  • 5
  • 4
  • +2
31 Comments
 
LVL 32

Expert Comment

by:jhance
Comment Utility
Well, oddly enough, C/C++ already has a BIT data type called a bitfield.  Perhaps this does what you want?  Programmers don't generally use this because it's very inefficient on the machine for execution speed.

Syntax

struct-declarator :

declarator
type-specifier declarator opt : constant-expression

Example:

struct mybits {
  unsigned short x : 1;
  unsigned short y : 1;
  unsigned short z : 1;
} MyBits;

....

MyBits.x = 0;
MyBits.y = 1;
MyBits.z = 0;

etc...

0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
The STL provides a std::bitset<number_of_bits> which is what you are looking for. If you want to use - I assume intel 486+ - assembly, you will find out pretty quickly, that any data type that is not 32bits wide will slow down execution. To keep things simple I'm not getting into mmx/sse/3dnow! programming. But even if you were able to come up with a data type that is only 1 bit wide, it will be zero padded to a DWORD boundary if it is pushed onto the stack. You probably already guessed it from the previous sentence, there is no way to have a data type in c++/asm that is only one bit wide -- 8bit is the bare minimum that can be accessed atomically.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
jhance, bitfields are far from being feasable. They can introduce terribly hard to find bugs and I already mentioned that in a response to previous question of MacLoed's.
0
 
LVL 32

Expert Comment

by:jhance
Comment Utility
>>8bit is the bare minimum that can be accessed atomically

And even that is not a given.  Not all processor archeitectures can access memory at the byte level.
0
 
LVL 32

Expert Comment

by:jhance
Comment Utility
I'm NOT defending bitfields or their use.  Please note my comments regarding them before you attack!  

I'm merely pointing out that they DO INDEED EXIST in C and C++ and have from very early on.  If you don't like the fact that they are in the language, take it up with the various committees that oversee such business.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
all x86 processors can, even p4's -- they may cause partial register stalls during read after write operations but exhibit a limited number of special cases where this doesn't happen, SUB and XOR being among them, if I'm not totally mistaken.
0
 
LVL 32

Expert Comment

by:jhance
Comment Utility
So I guess your world is limited to X86 processors.  Note that I said "not all PROCESSOR architectures".  I said nothing about X86.  This topic, being C++, could be talking about something other than X86 and perhaps it even has a single-bit instruction.  There have been such beasts.  Remember the RCA COSMAC CPU?  It had NO on-chip registers but did have a bit-level memory access.  Goofy architecture but very "cool" for its day.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
jhance, where exactly did you spot the attack? I'm just curious.

On the "DO INDEED EXIST"-business. They don't exist consistently across a wide range of commonly used compilers. They even do have inconsistent behaviour on msvc6 with optimizations turned on and off. So you may argue that they are written down in the ISO-standard. I, on the other hand, would rather be safe than sorry when producing production quality code.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
No, MacLeod did not limit his/her question to x86 platforms. With this platform being the most widely used one these days, I just took a chance and added to the question. Not that much of an offence, or do you think so?
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
So to finally answer the question: You can try to make a data type 1 bit wide through c++, but you cannot count on it being represented as such in memory, nor should you access it as though it were.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
MacLeod,
You can also consider using std::vector<bool> for your requirements.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
MacLeod,

If you know the size at run time, you probably want to use the std::bitset method that fl0yd suggested.
If need to determind the size at runtime, then using std::vector<bool> would be a better method.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
Correction:
If you know the size at "compile" time, you probably want to use the std::bitset method that fl0yd suggested.
If need to determind the size during runtime, then using std::vector<bool> would be a better method.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
Axter, how can you determine the size during runtime using a std::vector<bool>?
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>Axter, how can you determine the size during runtime
>>using a std::vector<bool>?

Just as you can determind the number char in a std::vector<char> at runtime.

You can use resize() member function to set std::vector<bool> to the required size.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
I think you are mixing up two things here, Axter. The member function std::vector<>.size() returns the number of ITEMS, not the number of bytes even less the number of bits in the container. As far as I know there is no way to get hold of the actually used storage location. Neither can you find out the size of the allocated memory -- you can find out how many items the std::vector<> can have until it will have to resize internally through the member function capacity(). But you cannot get to the internally used structures used to store the information. Neither should you even try to, since this stuff is all implementation dependant and can change without further notice.
0
 

Author Comment

by:MacLeod
Comment Utility
Well, so far nobody has actually answered my question and I don't know why you are squabbling over it.  I know about bitfields and <bitset>.  I wanted to know if it is possible to create my own 1 bit data type like in other languages irrespective of the cpu, because Iv'e done it on motorola's, DSP's, RISC types, to mention a few.  Not, however under C++.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
May I quote myself?: "So to finally answer the question: You can try to make a data type 1 bit wide through c++, but you cannot count on it being represented as such in memory, nor should you access it as though it were."

You are mixing up two things here -- a platform independent and a completely platform dependent programming language, i.e. c++ and asm. In assembly it depends only on the hardware whether you can have 1bit-data-types. In c++ you have the extra indirection of the compiler -- you will never (*NEVER*) ever find out directly how many bits wide a data type will be. You can try to use bitfields but it is not guaranteed that data is aligned exactly in the way you planned.

Now tell me again, are you sure your question hasn't been answered yet?
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
Or, if you prefer to approach the subject from another perspective:

By definition:
* sizeof( char ) == sizeof( unsigned char ) == sizeof( signed char ) == 1
* sizeof( char ) <= sizeof( short ) <= sizeof( int ) <= sizeof( long )
* sizeof( bool ) is implementation defined and doesn't necessarily have to be 1
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
To make it yet easier for you to find out for any specific platform the bitcount of every data type:

template<typename T> unsigned int bit_count() {
    T t = 1;
    unsigned int cnt = 1;
    while( t <<= 1 )
        ++cnt;
    return( cnt );
}

int main( int argc, char* argv[] ) {
    unsigned int cnt_char = bit_count<char>();
    unsigned int cnt_bool = bit_count<bool>();
    unsigned int cnt_short = bit_count<short>();
    // and so on...
    return( 0 );
}
0
 
LVL 22

Accepted Solution

by:
ambience earned 200 total points
Comment Utility
a language providing you means of making a 1 bit data-type and the actual memory representation of it in memory are two different things. If Ada runs on x86 then i dont think there is a real 1-bit data-type. It depends upon the sizeof bytes that we have (logically saying)

sizeof(byte) = 8 bits  // x86
sizeof(byte) = 7 bits  // some architecture i cant remember
..
sizeof(byte) = 1 bit  //  maybe maybe

there do exist some machines where a byte is greater than 8 bits.

>> is possible to create my own 1 bit data type like in other languages irrespective of the cpu

If by creating you mean an actual storage of 1 bit then the answer is no (depends in fact), and if it means a data-type that represents a bit then the answer is yes.

most of the experts have already explained that, i would rather like to change the question a bit, so that is it possible to emulate/simulate/represent my own 1 bit data-type in C++ like i can do in any other language irrespective of the cpu.

And the answer is yes. refer to the post regarding bitfields.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
To fill in the last gaps: If you are able to find a compiler that produces an executable from the following code, you have found a c++-compiler/machine-combination that gives you the opportunity to make up your own 1-bit data type in c++.


#include <iostream>

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]

int main( int argc, char* argv [] ) {
    C_ASSERT( 0 == ( (unsigned char)1 << 1 ) );
    std::cout << "wow, this compiler and machine support 1bit-char's" << std::endl;
    return 0;
}
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
p.s.: if the code compiles, your 1bit-data type is called 'char'.
0
 

Author Comment

by:MacLeod
Comment Utility
fl0yd,
That code does not compile.  There's a problem with that array macro you came up with.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
Well, you see, I said *IF* you find a compiler and machine where this code *DOES* compile you have found a way to define a 1-bit data type through c++. If it doesn't compile, you just cannot have a 1-bit data type on that machine/compiler.

On the macro: as much as I'd like to take credit for this nifty piece of code, I didn't invent it. It's functionality is to have a *COMPILE-TIME* check. If the condition isn't met, the code won't compile and the compiler tells you where this condition was requested. Sp let's assume your code relies on the fact that an 'int' is 32bits wide, put the following line of code to make sure you won't get undefined behaviour:

C_ASSERT( ( 0 == (int)1 << 32 ) && ( 0 != (int)1 << 31 ) );
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
p.s.: The error message should be something like 'subscript out of range'
0
 

Author Comment

by:MacLeod
Comment Utility
I know what you *SAID*.  I was making you aware that I tried it and it didn't work.  Don't be so *UPITTY*.  If you can't be nice, then don't answer *MY* posts.  And the error is: Array must have at least one element.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
Well, you see, I said the error message should be *SOMETHING LIKE* ... Since error messages aren't part of the ANSI/ISO-standard they can differ from compiler to compiler. So if your compiler tells you that an array must have at least one element does that contradict my compilers message that the [array] subscript is out of range? Out of range means either above maximum or below minimum.

Don't get all that upset, after all you said "There's a problem with that array macro you came up with". Definately not the most friendly way of putting it. May I remind you that you also said "That code". Not really friendly either. Furthermore, you claimed, that your question hasn't been answered but rather people are "squabbling over it", when it has long been answered. Indepth even. I assume there are people out there that would understand that I may be loosing my patience after a while.

Conclusion: You did get an answer to your question. No. There is no way to create a data type in c++ that is guaranteed to be 1 bit wide.
I provided you with code that you can use to verify what has been said. I provided you with code that may even be regarded as non-trivial. Plus I directed your attention to a nice macro that performs compile-time rather than run-time checking. This one - even though windows-coders may have run into it - can certainly be regarded as non-trivial knowledge that could come handy one day, especially when you're dealing with issues like in this thread.
0
 

Author Comment

by:MacLeod
Comment Utility
I think you think you know everything frojm your extremely condescending tone in practicaly every post that you make.  Furthermore, I don't care for your comments and have yet to find an acceptable one.  At any rate, I wouldn't take your advice if it were to save my life.  Quit trying to prove that you know everything and just help out.  If you get fed up, then don't comment any more to the posts that your fed up with.  And that's all I have to say about that.
0
 

Author Comment

by:MacLeod
Comment Utility
Thank you for the friendly answer.  This is all I need.  I'll just make do without an actual bit type that is stored as 1-bit in memory.  Heck, everyone else does.  This was mainly for my own edification.  I like to try things that are difficult to do.  Thank you agin for the answer.  I bumped the points to 200 for you.
0
 
LVL 8

Expert Comment

by:fl0yd
Comment Utility
So MacLeod, good luck to you then -- with the attitude you have you will need lots of it doing "things that are difficult to do".
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now