Linux Kernel Device Driver With C and C++

D

deech

Hi all,
I hope this is the right place to ask this, but I want to write a device driver for Linux that offloads the main portion of the logic to a C++ file and `extern` the relevant pieces for inclusion in the main `C` file.

I've successfully created a `hello world` executable but I don't know how to write the Makefile that will include the C++ library and compile it to a `.ko`. The simple tutorials don't seem to help.

Any help is appreciated.
-deech
 
A

Angel

Hi all,
I hope this is the right place to ask this, but I want to write a device
driver for Linux that offloads the main portion of the logic to a C++ file
and `extern` the relevant pieces for inclusion in the main `C` file.

I've successfully created a `hello world` executable but I don't know how
to write the Makefile that will include the C++ library and compile it to
a `.ko`. The simple tutorials don't seem to help.

Try this site:
http://kernelnewbies.org/

Just a word of warning; Linux kernel development is done in C only and
many there are pretty hostile to any suggestions that it should be done
in C++. (I personally take no stance on the matter, whatever works for
you is good enough.) Be prepared for some pretty harsh reactions.
 
E

Edward A. Falk

Try this site:
http://kernelnewbies.org/

Just a word of warning; Linux kernel development is done in C only and
many there are pretty hostile to any suggestions that it should be done
in C++.

Good advice. Be aware that kernel programming is a radically different
environment from user-level programming. Most significantly, there is
no libc so many of the system services you take for granted in your usual
programming environment are not available. This will go double for C++,
and frankly, I'd be surprised if you could make it work unless you're
very very careful.
 
A

Andrew Cooper

Try this site:
http://kernelnewbies.org/

Just a word of warning; Linux kernel development is done in C only and
many there are pretty hostile to any suggestions that it should be done
in C++. (I personally take no stance on the matter, whatever works for
you is good enough.) Be prepared for some pretty harsh reactions.

As a Xen hypervisor and Linux kernel developer myself, I offer this rule
of thumb. Only stuff which absolutely must be in the kernel should be
in the kernel. Everything else should be in userspace.

On a technical note, your chances of getting C++ working at all as a
kernel module is virtually 0. You certainly wont be able to do
exceptions or RTTI, and I cant offhand think of a way you would
implement even the simple things like global constructors/destructors.
On top of that, you will not have any libraries, and good luck using the
kernel internal headers with C++ (given all of the C-only syntax they use).

Dare I ask what your device driver is attempting to do?

~Andrew
 
J

James Kuyper

On a technical note, your chances of getting C++ working at all as a
kernel module is virtually 0. You certainly wont be able to do
exceptions or RTTI, and I cant offhand think of a way you would
implement even the simple things like global constructors/destructors.
On top of that, you will not have any libraries, and good luck using the
kernel internal headers with C++ (given all of the C-only syntax they use).

Ordinarily, I'd expect that if I used a C++ compiler essential as if it
were C compiler - using only features that C++ shares with C, and using
them only in ways that have the same meaning in C as in C++, and making
appropriate use of extern "C" - that it shouldn't be a problem.
However, your comment about "C-only syntax" would suggest otherwise.
What specific types of syntax are you referring to? Are these C90
features that were dropped in C99, such as implicit int, or C99 features
which have not yet been added to C++, such as restrict, or C features
that were never supported in C++, but which few sane C programmers have
voluntarily used for at least a decade, such as non-prototyped function
declarations, or something else?

When I think of how C++ differs from C, ctors and dtors are an important
part of it, but I also think about member functions, inheritance,
(single and multiple), function overloading, operator overloads,
template classes. template functions, member access restrictions,
virtual members, and virtual inheritance. Do any of these features cause
problems for kernal programming? Most of these features can be emulated
in C code; which is in fact how the earliest C++ compilers were
implemented, which is why I'd be surprised if they were problematic. If
they are, would the corresponding C code be equally problematic?
 
I

Ian Collins

Ordinarily, I'd expect that if I used a C++ compiler essential as if it
were C compiler - using only features that C++ shares with C, and using
them only in ways that have the same meaning in C as in C++, and making
appropriate use of extern "C" - that it shouldn't be a problem.
However, your comment about "C-only syntax" would suggest otherwise.
What specific types of syntax are you referring to? Are these C90
features that were dropped in C99, such as implicit int, or C99 features
which have not yet been added to C++, such as restrict, or C features
that were never supported in C++, but which few sane C programmers have
voluntarily used for at least a decade, such as non-prototyped function
declarations, or something else?

When I think of how C++ differs from C, ctors and dtors are an important
part of it, but I also think about member functions, inheritance,
(single and multiple), function overloading, operator overloads,
template classes. template functions, member access restrictions,
virtual members, and virtual inheritance. Do any of these features cause
problems for kernal programming? Most of these features can be emulated
in C code; which is in fact how the earliest C++ compilers were
implemented, which is why I'd be surprised if they were problematic. If
they are, would the corresponding C code be equally problematic?

I can't speak for Linux modules, but in the BSD/Solaris world your
observations are correct. As long as the C++ code does not require
runtime library support, it is fine to use in kernel land. If you do
accidentally use a feature that does require runtime library support,
your code won't load and you soon realise the error of your ways. Been
there and done that!

In BSD/Solaris drivers, there are per-driver and per-instance interfaces
and variables that map well to static and non-static class members.
 
L

Lew Pitcher

Sorry clc, but this thread has gone on long enough

Hi all,
I hope this is the right place to ask this,

No. It isn't.
but I want to write a device
driver for Linux that offloads the main portion of the logic to a C++ file
and `extern` the relevant pieces for inclusion in the main `C` file.

Not a good idea. You might want to read the Linux-kernel Mailinglist faq,
especially question 15.3 (http://www.tux.org/lkml/#s15-3)
I've successfully created a `hello world` executable but I don't know how
to write the Makefile that will include the C++ library and compile it to
a `.ko`. The simple tutorials don't seem to help.

There are no tutorials because it is discouraged (read "forbidden by the
lead kernel developers).

The basic point is that, for various reasons (good or bad), the Linux kernel
developers do not want, and do not support, kernel development using C++ in
any form. If, as you say in a later post, you intend to code your C++
in 'extern "C" ' format, there is no reason to avoid coding your kernel
development directly in C /instead of/ C++.

OTOH, if you intend to use /even one/ feature of C++ that is not supported
directly in C, then you are out of luck. And, name-mangling counts as a
feature.

HTH
 
M

Melzzzzz

I can't speak for Linux modules, but in the BSD/Solaris world your
observations are correct.

Linus is hostile toward C++ , so they would not accept
any driver written in C++ ;)
For home use I think there is no problem to write driver
in any language, even modify kernel to support rtti
and exceptions ;)
 
I

Ian Collins

Sorry clc, but this thread has gone on long enough



No. It isn't.


Not a good idea. You might want to read the Linux-kernel Mailinglist faq,
especially question 15.3 (http://www.tux.org/lkml/#s15-3)


There are no tutorials because it is discouraged (read "forbidden by the
lead kernel developers).

The basic point is that, for various reasons (good or bad), the Linux kernel
developers do not want, and do not support, kernel development using C++ in
any form. If, as you say in a later post, you intend to code your C++
in 'extern "C" ' format, there is no reason to avoid coding your kernel
development directly in C /instead of/ C++.

That does not make sense. In C++, extern "C" is merely a means to
provide linkage compatibility with C. It does not influence what goes
on inside a function or module.
OTOH, if you intend to use /even one/ feature of C++ that is not supported
directly in C, then you are out of luck. And, name-mangling counts as a
feature.

Name mangling is a consequence of C++ features, not a feature. If all
the public interfaces of a module are declared extern "C", what goes on
inside is irrelevant.
 
A

Andrew Cooper

Ordinarily, I'd expect that if I used a C++ compiler essential as if it
were C compiler - using only features that C++ shares with C, and using
them only in ways that have the same meaning in C as in C++, and making
appropriate use of extern "C" - that it shouldn't be a problem.
However, your comment about "C-only syntax" would suggest otherwise.
What specific types of syntax are you referring to? Are these C90
features that were dropped in C99, such as implicit int, or C99 features
which have not yet been added to C++, such as restrict, or C features
that were never supported in C++, but which few sane C programmers have
voluntarily used for at least a decade, such as non-prototyped function
declarations, or something else?

I was thinking of C99 struct initializer syntax which is invalid in C++,
although thinking about it, I am failing to think of any Linux examples
offhand. (The Xen headers are full of useful macros, such as the
spinlock ones, which wrap this functionality.)

However, the Linux headers certainly do have variables called 'new' in
prototypes and structure declarations, which are sure to spoil the day
of any well meaning C++ compiler.
When I think of how C++ differs from C, ctors and dtors are an important
part of it, but I also think about member functions, inheritance,
(single and multiple), function overloading, operator overloads,
template classes. template functions, member access restrictions,
virtual members, and virtual inheritance. Do any of these features cause
problems for kernal programming? Most of these features can be emulated
in C code; which is in fact how the earliest C++ compilers were
implemented, which is why I'd be surprised if they were problematic. If
they are, would the corresponding C code be equally problematic?

Local static variables and global ctors and dtors require runtime
support, and the usual trick for c/dtors of trying to play section magic
to make this happen would require you to roll your own linked kernel
module rather than using the regular Kbuild system.

Local c/dtors are fine, as are most of the of the other language
features you list from a "it will compile" standpoint (other than
needing a symbol to link against for pure virtual calls)

A lot of these feature can be emulated in C code, and one could argue
that certain design patterns in the kernel are moving closer towards a
C++ way of thinking, most notably the PVOPS code looks very much like
virtual inheritance.


There are issues which arise from the C++ mentality. In code where
brevity and cache alignment is key for performance, the concept of
private member variables is unhelpful. The concept of inheritance tends
to lump some X along with something Y which is half-similar, but this is
not a data pattern commonly encountered. I am struggling to think of a
single situation where operator overloading would be useful, or indeed
clear in its context, given the typical data us.

And from a technical viewpoint, templates are fantastically bad for
compiled code and data size, typically making N identical or almost
identical copies of each different instantiation. Constructing objects
in C++ is far more work than making a new stuct in C, especially if
there is any inheritance involved. Optimising C++ is harder than
optimising C; The compiler, in general, cannot inline even the most
simple one-line virtual function call.


So overall, (other than the inclusion problem), excluding the C++
features which require runtime support, you can get a working solution.
However, because of the differences between C and C++, there is a large
difference between working and working well.

Don't get me wrong - there are times and places for both C and C++ and I
use both frequently, but in my opinion, a kernel is not a place for C++.

~Andrew
 
J

Jorgen Grahn

Good advice. Be aware that kernel programming is a radically different
environment from user-level programming. Most significantly, there is
no libc so many of the system services you take for granted in your usual
programming environment are not available.

That part is not so bad IME. Most of the relevant parts are there. The
irrelevant ones are not, of course; there is no normal file I/O
because there is no normal file system, and so on.

/Jorgen
 
J

Jorgen Grahn

On Sat, 2012-11-03, Andrew Cooper wrote:

[C++ in Linux kernel code]
There are issues which arise from the C++ mentality.
[...]

There are different C++ mentalities. You seem to be thinking of
heavy-handed object-oriented programming, but that's not the only way
to use the language.

/Jorgen
 
J

James Kuyper

On 02/11/2012 22:45, James Kuyper wrote: .... ....
However, the Linux headers certainly do have variables called 'new' in
prototypes and structure declarations, which are sure to spoil the day
of any well meaning C++ compiler.

Yes, use of C++ reserved identifiers would certainly be a problem.
Local static variables and global ctors and dtors require runtime
support, ...


I've never had to do any kernal programming, so I don't understand what
the relevant restrictions are, or why they exist. What is problematic
about local static variables? They're not specific to C++, so I assume
that the following C code would also be problematic?:

int save_val(int i)
{
static int saved;
int retval = saved;
saved = i;
return retval;
}
There are issues which arise from the C++ mentality. In code where
brevity and cache alignment is key for performance, the concept of
private member variables is unhelpful. The concept of inheritance tends
to lump some X along with something Y which is half-similar, but this is
not a data pattern commonly encountered. I am struggling to think of a
single situation where operator overloading would be useful, or indeed
clear in its context, given the typical data us.

The built-in C types fall into a number of categories, based upon which
operators work on them: arithmetic types, pointer types, array types,
functions. Operator overloads work best when they make something that is
of class type work like a member of one of those categories: extended
numeric types such as quaternions or arrays, smart pointers, containers,
or function objects. They only lead to confusion when used for other
purposes. I don't imagine there's much need for extended arithmetic
types in kernal programming. However, it seems to me that various kinds
of smart pointers or containers could be useful, unless they can't be
properly implemented. If there's any place where kernel code passes
around function pointers, passing around function objects might be a
reasonable alternative.
And from a technical viewpoint, templates are fantastically bad for
compiled code and data size, typically making N identical or almost
identical copies of each different instantiation.

The point of having a template is that you have code that needs to be
duplicated, depending upon the template's parameters. Properly used, you
shouldn't be able to avoid the duplication by using C (or the C subset
of C++). If there's code that wouldn't have to be duplicated if you were
using C, then in C++ that code should be factored outside of the template.
Of course, not everything that should be done, is done - I've seen that
a lot in C, and now that I've working on a C++ project, I'm seeing the
same thing in C++. But that's due to misuse of templates, not because of
templates themselves.
... Constructing objects
in C++ is far more work than making a new stuct in C, especially if
there is any inheritance involved.

If you can construct an object in C without much work, you can write C++
code that requires no more work than the C code to construct it; it
will, in general, be the same (or almost the same) code. The only reason
why C++ construction gets more complicated is if you want to make use of
a C++ feature not supported by C, and if you're sane, you only do that
if that feature provides some benefit that justifies the extra work. I
don't see that as justifying an avoidance of C++.

Optimising C++ is harder than
optimising C; The compiler, in general, cannot inline even the most
simple one-line virtual function call.

It's only meaningful to compare optimization of equivalent code. C
doesn't support virtual function calls; the closest equivalent is C
requires use of a function pointer. Can a typical C compiler do any
better of a job inlining calls through function pointers than a C++
compiler can do of inlining virtual function calls?
 
A

Andrew Cooper

I've never had to do any kernal programming, so I don't understand what
the relevant restrictions are, or why they exist. What is problematic
about local static variables? They're not specific to C++, so I assume
that the following C code would also be problematic?:

Sorry - let me be more clear. In an environment you completely control,
adding 'runtime support' for global c/dtors and local static variables
is quite easy (See http://wiki.osdev.org/C++ ). My issue, in this case,
with them is that I cant think of a way of a Linux kernel module adding
its own runtime support (other than bypassing the Kbuild system and
attempting to link it up yourself)
int save_val(int i)
{
static int saved;
int retval = saved;
saved = i;
return retval;
}

There is a difference between how GCC and G++ treat static local
variables. G++ generates extra code to put a mutex around it to prevent
concurrent initialisation, and this is what requires the runtime
support. (Admittedly this is only G++. Other C++ compilers wont, but
best of luck to you trying to compile even the kernel header files
The built-in C types fall into a number of categories, based upon which
operators work on them: arithmetic types, pointer types, array types,
functions. Operator overloads work best when they make something that is
of class type work like a member of one of those categories: extended
numeric types such as quaternions or arrays, smart pointers, containers,
or function objects.

And this is all perfectly reasonable in userspace, but not in kernel
space. Floating point calculations are to be avoided at almost any
cost, because they are not useful in the vast majority of cases, and
incur extra overhead if the kernel needs to save/restore its own
floating point state as well as that of the tasks it is scheduling.
...They only lead to confusion when used for other
purposes. I don't imagine there's much need for extended arithmetic
types in kernal programming. However, it seems to me that various kinds
of smart pointers or containers could be useful, unless they can't be
properly implemented. If there's any place where kernel code passes
around function pointers, passing around function objects might be a
reasonable alternative.

What form of smart pointers? I assume you mean shared_ptr. They are
just a pointer and a reference count. In the C++ world, the refcount
lives with the pointer, while in the kernel, objects needing refcounting
have a ref count in them. The C world has better locality of data in
the cache, while the C++ world also suffers from the same indirection
problem as function pointer objects.

Lets consider the difference between passing a function pointer in C
(which fits in a register, or single word on the stack), with passing a
C++ function pointer object. The C++ function pointer object is
necessarily as large.

How about calling this function pointer? In C, you would load it off
the stack, or from ram, into a register, and 'call's the address in the
register. In C++, you grab a pointer to the function pointer object,
pass it to the operator() function for your object, which deferences the
pointer, finds the function pointer member variable, loads this into a
register and 'call's the address in the register.

So yes - both of these will indeed work, but see the difference between
working and working and working well. One of the worst things a kernel
can do is needlessly follow pointers, as this takes more time, and leads
to cache misses. The C way of doing things results in less memory
overhead, (both in terms of code size and data size), involves fewer
pointers to follow, and has better cache locality.
The point of having a template is that you have code that needs to be
duplicated, depending upon the template's parameters. Properly used, you
shouldn't be able to avoid the duplication by using C (or the C subset
of C++). If there's code that wouldn't have to be duplicated if you were
using C, then in C++ that code should be factored outside of the template.
Of course, not everything that should be done, is done - I've seen that
a lot in C, and now that I've working on a C++ project, I'm seeing the
same thing in C++. But that's due to misuse of templates, not because of
templates themselves.

Agreed, subject to your statement of "Properly used". However, I cant
think of a single case where templates would be useful.
If you can construct an object in C without much work, you can write C++
code that requires no more work than the C code to construct it; it
will, in general, be the same (or almost the same) code. The only reason
why C++ construction gets more complicated is if you want to make use of
a C++ feature not supported by C, and if you're sane, you only do that
if that feature provides some benefit that justifies the extra work. I
don't see that as justifying an avoidance of C++.



It's only meaningful to compare optimization of equivalent code. C
doesn't support virtual function calls; the closest equivalent is C
requires use of a function pointer. Can a typical C compiler do any
better of a job inlining calls through function pointers than a C++
compiler can do of inlining virtual function calls?

Ok - fair points. As with templates, I cant think of a useful use case
for compound objects. From a naive point of view, virtual functions via
an interface design model could seem very attractive and useful in a
kernel environment. However, a virtual function call is 2 pointers to
follow rather than one, going back to the performance aspect.

The point I was trying to get across is that C++ opens up a whole
toolkit of new and shiny features which are not needed and when used
with the best of intentions lead to poor performance. This alone is the
biggest reason why I believe C++ should not be used.
 
Ö

Öö Tiib

What form of smart pointers? I assume you mean shared_ptr.

I expect with "smart_pointer" mentioned that std::unique_ptr is used.
It causes minimal overhead compared to raw pointer (one instruction per
access) but adds lot of clarity and safety.
They are
just a pointer and a reference count. In the C++ world, the refcount
lives with the pointer, while in the kernel, objects needing refcounting
have a ref count in them. The C world has better locality of data in
the cache, while the C++ world also suffers from the same indirection
problem as function pointer objects.

std::shared_ptr? It is truly heavyweight so one should not use it just like
that for everything (like lot of noobs seem to do). It has separate dynamic
object for containing weak_count, shared_count, deleter functor and raw
pointer.

You assign to it also some sins that you think it has but it does not have.
Locality equal to C of that ref-counter object is gained by using
std::make_shared that achieves that both objects are allocated adjacent
in memory with a single malloc.
Lets consider the difference between passing a function pointer in C
(which fits in a register, or single word on the stack), with passing a
C++ function pointer object. The C++ function pointer object is
necessarily as large.

"Function pointer object"??? You are confused here. Function object, usually
passed by value. The function if it is simple is often inlined by optimizing
compiler to point of usage and the optimization will cause efficiency
gain. That is the reason why std::sort<>() usually outperforms qsort().

In general, noobs needing tutorials should start with something simpler
than writing drivers for OS kernels on any case, neither C nor C++ can
help them enough there.
 
J

James Kuyper

On 03/11/2012 13:33, James Kuyper wrote: .... ....
What form of smart pointers? I assume you mean shared_ptr.

I meant smart pointers in general: any class type that uses operator
overloads to emulate a pointer type, but with extra features added. Any
feature that reduces the likelihood of dereferencing a pointer that
cannot be safely dereferenced, or of producing a memory leak, has some
potential value in user space programming, though it's always a matter o
judgment whether the value is worth the associated cost. Is there no
such feature that would be of any use in kernel programming?
 
I

Ian Collins

And this is all perfectly reasonable in userspace, but not in kernel
space. Floating point calculations are to be avoided at almost any
cost, because they are not useful in the vast majority of cases, and
incur extra overhead if the kernel needs to save/restore its own
floating point state as well as that of the tasks it is scheduling.


What form of smart pointers? I assume you mean shared_ptr. They are
just a pointer and a reference count. In the C++ world, the refcount
lives with the pointer, while in the kernel, objects needing refcounting
have a ref count in them. The C world has better locality of data in
the cache, while the C++ world also suffers from the same indirection
problem as function pointer objects.

In C++, you can choose how you associate the object pointer and the
reference count, so there's no loss of efficiency there. There isn't
any loss with access either (modulo any optional error checking).
Lets consider the difference between passing a function pointer in C
(which fits in a register, or single word on the stack), with passing a
C++ function pointer object. The C++ function pointer object is
necessarily as large.

If the function pointer object isn't reference counted, it will be the
same size as the equivalent raw pointer.
How about calling this function pointer? In C, you would load it off
the stack, or from ram, into a register, and 'call's the address in the
register. In C++, you grab a pointer to the function pointer object,
pass it to the operator() function for your object, which deferences the
pointer, finds the function pointer member variable, loads this into a
register and 'call's the address in the register.

Er, no. Calling a function pointer compiles to the exact same code a
calling a raw pointer, modulo any optional error checking. The caveat
is important there, with a C++ smart pointer you can globally enable
access checking without an awful lot of messy conditional compilations.
So yes - both of these will indeed work, but see the difference between
working and working and working well. One of the worst things a kernel
can do is needlessly follow pointers, as this takes more time, and leads
to cache misses. The C way of doing things results in less memory
overhead, (both in terms of code size and data size), involves fewer
pointers to follow, and has better cache locality.

In practice, the two techniques have the same overhead.
Agreed, subject to your statement of "Properly used". However, I cant
think of a single case where templates would be useful.

The case we have just been discussing: resource management.
The point I was trying to get across is that C++ opens up a whole
toolkit of new and shiny features which are not needed and when used
with the best of intentions lead to poor performance. This alone is the
biggest reason why I believe C++ should not be used.

Any more capable tool used incorrectly can cause you problems. Using
that argument as the justification for not using it is poor reasoning.

I've been countering the same FUD (usually be actually using C++ in
those areas) for more than a decade now in the embedded/driver/kernel
space and I'm amazed it's still being propagated.
 
K

Keith Thompson

Andrew Cooper said:
On 03/11/2012 13:33, James Kuyper wrote: [...]
int save_val(int i)
{
static int saved;
int retval = saved;
saved = i;
return retval;
}

There is a difference between how GCC and G++ treat static local
variables. G++ generates extra code to put a mutex around it to prevent
concurrent initialisation, and this is what requires the runtime
support. (Admittedly this is only G++. Other C++ compilers wont, but
best of luck to you trying to compile even the kernel header files
[...]

I just compiled the above function with both gcc and g++ (version
4.7.0). The generated code was identical apart from a few different
identifiers.

Is there some g++ option that tells it to create a mutex?
 
S

SG

Am 03.11.2012 21:22, schrieb Keith Thompson:
Andrew Cooper said:
On 03/11/2012 13:33, James Kuyper wrote: [...]
int save_val(int i)
{
static int saved;
int retval = saved;
saved = i;
return retval;
}

There is a difference between how GCC and G++ treat static local
variables. G++ generates extra code to put a mutex around it to prevent
concurrent initialisation, and this is what requires the runtime
support. (Admittedly this is only G++. Other C++ compilers wont, but
best of luck to you trying to compile even the kernel header files
[...]

I just compiled the above function with both gcc and g++ (version
4.7.0). The generated code was identical apart from a few different
identifiers.

Is there some g++ option that tells it to create a mutex?

It does not surprize me that the code is equal. There is no dynamic
initialization of 'saved' going on. What C++11 guarantees is that a
dynamic initialization is thread-safe. But C doesn't even allow this
kind of dynamic initializations. What do I mean by "dynamic
initialization"? Here's a C++ example:

int reverse_increment_256(int j)
{
int bitmask = 128;
while (bitmask) {
j ^= bitmask;
if ((j & bitmask)!=0) break;
bitmask >>= 1;
}
return j;
}

const unsigned char* get_bit_reverse_256_table()
{
static const int* table = []()->unsigned char*{
unsigned char* table = new int[256];
for (int i=0, j=0; i<256; ++i) {
table = j;
j = reverse_increment(j);
}
return table;
}();
return table;
}

(untested)

Here, the initializer of the static variable 'table' is dynamic in the
sense that the function call has to be performed during runtime. C++11
makes sure that this dynamic initialization is properly locked so that
in case the table has not yet been computed and two threads invoke
get_bit_reverse_256_table concurrently, the table is just computed once
properly.

I don't know whether G++ already supports that. Maybe you have to turn
on this behaviour by using -std=c++0x or -std=c++11 .

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top