From: LiloLilo on
Hi all,

the following function writes n bits data to file. Parameter named
'Data' contains the value to be written, 'Length' contains the number
of bits of 'Data' to write. This function uses a static buffer named
BitBuffer to store bits between calls. When BitBuffer is full it is
written to file.


void WriteBitsToFile(unsigned Data, unsigned Length, std::ofstream &
OutFile) {


static unsigned BitBuffer = 0; static unsigned BitCounter =
0;


for (unsigned i = Length; i --; ) {


(BitBuffer <<= 1) |= ((Data >> i) & 0x1); BitCounter +
+;


if (BitCounter == 32) { OutFile.write((char *) &
BitBuffer,
sizeof(BitBuffer)); BitCounter = 0; }
}


TotalBitCounter += Length;



}


The function works fine, but if I change 'Data' to a templated
variable, BitBuffer gets flushed to 0 at every call, so it does not
retains values between calls. Please note that calls are made always
with the same type for T2 (int) so if I am not wrong it would retain
the value but it doesn't. Why?

template <typename T2> void WriteBitsToFile(T2 Data, unsigned Length,
std::ofstream & OutFile) {


static unsigned BitBuffer = 0; static unsigned BitCounter =
0;


for (unsigned i = Length; i --; ) {


(BitBuffer <<= 1) |= ((Data >> i) & 0x1); BitCounter +
+;


if (BitCounter == 32) { OutFile.write((char *) &
BitBuffer,
sizeof(BitBuffer)); BitCounter = 0; }
}


TotalBitCounter += Length;



}


Thank you all for help.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Paul Bibbings on
LiloLilo <danilobrambilla(a)tiscali.it> writes:

> Hi all,
>
> the following function writes n bits data to file. Parameter named
> 'Data' contains the value to be written, 'Length' contains the number
> of bits of 'Data' to write. This function uses a static buffer named
> BitBuffer to store bits between calls. When BitBuffer is full it is
> written to file.

[code snipped - tidied for format and invoked below]

> The function works fine, but if I change 'Data' to a templated
> variable, BitBuffer gets flushed to 0 at every call, so it does not
> retains values between calls. Please note that calls are made always
> with the same type for T2 (int) so if I am not wrong it would retain
> the value but it doesn't. Why?

I find that I am not able to reproduce the problem you are describing.
Perhaps you could provide a complete example that includes invocation
and produces the behaviour you describe for your implementation, and
give the compiler/version also. With the following extension of your
code (to include merely invocation):
19:33:44 Paul Bibbings(a)JIJOU
/cygdrive/d/CPPProjects/CLCPPM $cat bit_buffer.cpp
// bit_buffer.cpp

#include <fstream>

unsigned TotalBitCounter = 0;

void WriteBitsToFile(unsigned Data,
unsigned Length,
std::ofstream & OutFile)
{
static unsigned BitBuffer = 0;
static unsigned BitCounter = 0;

for (unsigned i = Length; i--; ) {

(BitBuffer <<= 1) |= ((Data >> i) & 0x1);
BitCounter++;

if (BitCounter == 32) {
OutFile.write((char *) & BitBuffer, sizeof(BitBuffer));
BitCounter = 0;
}
}

TotalBitCounter += Length;
}

template <typename T2>
void WriteBitsToFile(T2 Data,
unsigned Length,
std::ofstream & OutFile)
{
static unsigned BitBuffer = 0;
static unsigned BitCounter = 0;

for (unsigned i = Length; i--; ) {

(BitBuffer <<= 1) |= ((Data >> i) & 0x1);
BitCounter++;

if (BitCounter == 32) {
OutFile.write((char *) & BitBuffer, sizeof(BitBuffer));
BitCounter = 0;
}
}

TotalBitCounter += Length;
}

int main()
{
std::ofstream out1("Out1.txt");
if (out1)
{
for (int i = 0; i < 2; ++i)
WriteBitsToFile(12345U, 16, out1);
}

std::ofstream out2("Out2.txt");
if (out1)
{
for (int i = 0; i < 2; ++i)
WriteBitsToFile<>(12345U, 16, out2);
}
}

for an implementation (gcc-4.4.3) that has a 32-bit unsigned type, the
result is two identical files. If I have understood your description of
the issue correctly I would have expected them to be different, had the
problem been reproducible.

Regards

Paul Bibbings

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 6 Jun., 17:14, LiloLilo <danilobrambi...(a)tiscali.it> wrote:
> Hi all,
>
> the following function writes n bits data to file. Parameter named
> 'Data' contains the value to be written, 'Length' contains the number
> of bits of 'Data' to write. This function uses a static buffer named
> BitBuffer to store bits between calls. When BitBuffer is full it is
> written to file.
>
> void WriteBitsToFile(unsigned Data, unsigned Length, std::ofstream &
> OutFile) {
>
> static unsigned BitBuffer = 0; static unsigned BitCounter =
> 0;
>
> for (unsigned i = Length; i --; ) {
>
> (BitBuffer <<= 1) |= ((Data >> i) & 0x1); BitCounter +
> +;
>
> if (BitCounter == 32) { OutFile.write((char *) &
> BitBuffer,
> sizeof(BitBuffer)); BitCounter = 0; }
> }
>
> TotalBitCounter += Length;
>
> }
>
> The function works fine, but if I change 'Data' to a templated
> variable, BitBuffer gets flushed to 0 at every call, so it does not
> retains values between calls. Please note that calls are made always
> with the same type for T2 (int) so if I am not wrong it would retain
> the value but it doesn't. Why?
>
> template <typename T2> void WriteBitsToFile(T2 Data, unsigned Length,
> std::ofstream & OutFile) {
>
> static unsigned BitBuffer = 0; static unsigned BitCounter =
> 0;
>
> for (unsigned i = Length; i --; ) {
>
> (BitBuffer <<= 1) |= ((Data >> i) & 0x1); BitCounter +
> +;
>
> if (BitCounter == 32) { OutFile.write((char *) &
> BitBuffer,
> sizeof(BitBuffer)); BitCounter = 0; }
> }
>
> TotalBitCounter += Length;
>
> }
>
> Thank you all for help.

Please show us a complete program that demonstrates
the problem directly. If your analysis would be
correct, it should probably be reproducible. E.g.
what is the outcome of the following program given
your compiler:

#include <iostream>

void foo() {
static int a = 0;
std::cout << a << ", ";
a += 1;
}

template<class>
void foo() {
static int a = 0;
std::cout << a << ", ";
a += 1;
}

int main() {
for (int i = 0; i < 3; ++i) {
foo();
}
std::cout << std::endl;
for (int i = 0; i < 3; ++i) {
foo<int>();
}
}

An conforming implementation should output:

0, 1, 2,
0, 1, 2,

Which compiler (including version) are you using?

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: LiloLilo on

>
> for an implementation (gcc-4.4.3) that has a 32-bit unsigned type, the
> result is two identical files. If I have understood your description of
> the issue correctly I would have expected them to be different, had the
> problem been reproducible.
>

Thank you all for your answers. This issue results to me in two
different files. I am using VC++ 2010 compiler, x86 code.
As the whole code is quite long and unnecessary, I'll post as soon as
possible a sample code to let you reproduce the problem.
I would like also to try with the codes you posted to test if it works
or not too.

Regards, D.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: LiloLilo on

> I find that I am not able to reproduce the problem you are describing.
> Perhaps you could provide a complete example that includes invocation
> and produces the behaviour you describe for your implementation, and
> give the compiler/version also.


Hi,

please try this code derived from the one you provided above. It
produces
two different files. Compiler is Visual C++ 2010

#include "stdafx.h"

#include <fstream>


unsigned TotalBitCounter = 0;


void WriteBitsToFile(unsigned Data,
unsigned Length,
std::ofstream & OutFile)
{
static unsigned BitBuffer = 0;
static unsigned BitCounter = 0;


for (unsigned i = Length; i--; ) {


(BitBuffer <<= 1) |= ((Data >> i) & 0x1);
BitCounter++;


if (BitCounter == 32) {
OutFile.write((char *) & BitBuffer, sizeof(BitBuffer));
BitCounter = 0;
}
}


TotalBitCounter += Length;
}


template <typename T2>
void WriteBitsToFile(T2 Data,
unsigned Length,
std::ofstream & OutFile)
{
static unsigned BitBuffer = 0;
static unsigned BitCounter = 0;


for (unsigned i = Length; i--; ) {


(BitBuffer <<= 1) |= ((Data >> i) & 0x1);
BitCounter++;


if (BitCounter == 32) {
OutFile.write((char *) & BitBuffer, sizeof(BitBuffer));
BitCounter = 0;
}
}


TotalBitCounter += Length;
}


int main()
{
std::ofstream out1("Out1.txt");
if (out1)
{
WriteBitsToFile(12345U, 2, out1);
WriteBitsToFile(12345U, 5, out1);
WriteBitsToFile(12345U, 8, out1);
WriteBitsToFile(12345U, 3, out1);
WriteBitsToFile(12345U, 12, out1);
WriteBitsToFile(12345U, 7, out1);
WriteBitsToFile(12345U, 14, out1);
WriteBitsToFile(12345U, 2, out1);
WriteBitsToFile(12345U, 5, out1);
WriteBitsToFile(12345U, 8, out1);
WriteBitsToFile(12345U, 3, out1);
WriteBitsToFile(12345U, 12, out1);
WriteBitsToFile(12345U, 7, out1);
WriteBitsToFile(12345U, 14, out1);
}


std::ofstream out2("Out2.txt");
if (out1)
{
WriteBitsToFile(12345U, 2, out2);
WriteBitsToFile(12345U, 5, out2);
WriteBitsToFile(12345U, 8, out2);
WriteBitsToFile(12345U, 3, out2);
WriteBitsToFile(12345U, 12, out2);
WriteBitsToFile(12345U, 7, out2);
WriteBitsToFile(12345U, 14, out2);
WriteBitsToFile(12345U, 2, out2);
WriteBitsToFile(12345U, 5, out2);
WriteBitsToFile(12345U, 8, out2);
WriteBitsToFile(12345U, 3, out2);
WriteBitsToFile(12345U, 12, out2);
WriteBitsToFile(12345U, 7, out2);
WriteBitsToFile(12345U, 14, out2);
}
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]