Skip to contentSkip to conversation

unhappy with current.h

DISCUSSION Daniele Lugli 10 participants 19 messages Oct 14, 2002 – Oct 15, 2002

lore
Share & tools
lore
#0 lore raw

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

*** one of my data structures has a field named 'current'. ***

Pretty common word, isn't it? Would you think it can cause such a trouble? But in some of my files I happen to indirectly include <asm/current.h> (kernel 2.4.18 for i386), containing the following line:

#define current get_current()

so that my structure becomes the owner of a function it has never asked for, while it looses a data member. gcc has nothing to complain about that.

In some other files I don't happen to include <asm/current.h>, so that there my structure is sound - but alas! has different size and different composition. Again, gcc has nothing to complain.

Moral of the story: in my opinion kernel developers should reduce to a minimum the use of #define, and preferably use words in uppercase and/or with underscores, in any case not commonly used words.
In the specific case the said #define just looks to save 6 keystrokes and I think it could have been completely avoided.

Regards, Daniele Lugli

#1 lore raw

From: Daniele Lugli <[email protected]>
Date: Mon, 14 Oct 2002 21:46:08 +0200

Moral of the story: in my opinion kernel developers should reduce to a minimum the use of #define, and preferably use words in uppercase and/or with underscores, in any case not commonly used words.

Or maybe you should change your datastructure to not have member names the conflict with 7 year old well defined global symbols in the Linux kernel?

#2 lore raw
Quoted 11 lines · David S. Miller

From: Daniele Lugli <[email protected]>
Date: Mon, 14 Oct 2002 21:46:08 +0200

Moral of the story: in my opinion kernel developers should reduce to a minimum the use of #define, and preferably use words in uppercase and/or with underscores, in any case not commonly used words.

Or maybe you should change your datastructure to not have member names the conflict with 7 year old well defined global symbols in the Linux kernel?

That's what I did.

What about, next time,

#define i j

??

Regards, DL

#3 lore raw
In reply to Daniele Lugli
Quoted 4 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

*** one of my data structures has a field named 'current'. ***

gcc -Wshadow

--cw

#4 lore raw
Quoted 8 lines · Chris Wedgwood
Quoted 4 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

*** one of my data structures has a field named 'current'. ***

gcc -Wshadow

Would it be a good idea to add -Wshadow to the kernel compile options by default ?

Rik

Signature · 3 lines
Bravely reimplemented by the knights who say "NIH".
http://www.surriel.com/		http://distro.conectiva.com/
Current spamtrap:  <a href=mailto:"[email protected]">[email protected]</a>
#5 lore raw
Quoted 2 lines · Rik van Riel

Would it be a good idea to add -Wshadow to the kernel compile options by default ?

Yes, I think so. Last time I tried this it produced quite a bit of output.

--cw

#6 lore raw
In reply to Rik van Riel
Quoted 6 lines · Rik van Riel
Quoted 5 lines · Chris Wedgwood
Quoted 2 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

*** one of my data structures has a field named 'current'. ***

gcc -Wshadow

Would it be a good idea to add -Wshadow to the kernel compile options by default ?

Yes.

Signature · 7 lines
Murray J. Root
------------------------------------------------
DISCLAIMER: http://www.goldmark.org/jeff/stupid-disclaimers/
------------------------------------------------
Mandrake on irc.freenode.net:
  #mandrake & #mandrake-linux = help for newbies 
  #mdk-cooker = Mandrake Cooker 
#7 lore raw
In reply to Rik van Riel
Quoted 6 lines · Rik van Riel
Quoted 5 lines · Chris Wedgwood
Quoted 2 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

*** one of my data structures has a field named 'current'. ***

gcc -Wshadow

Would it be a good idea to add -Wshadow to the kernel compile options by default ?

While I'm not defending macro abuse, please note that Daniele's problem appears to have been caused by using g++ instead of gcc or gcc -x c to compile a kernel module. Daniele's later example throws a syntax error in gcc, since the cpp output isn't legal C ...

Hence I fail to see the utility of hacking in kludges for something that's not supposed to work anyway.

#8 lore raw
Quoted 15 lines · Mikael Pettersson
Quoted 6 lines · Rik van Riel
Quoted 5 lines · Chris Wedgwood
Quoted 2 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

*** one of my data structures has a field named 'current'. ***

gcc -Wshadow

Would it be a good idea to add -Wshadow to the kernel compile options by default ?

Quoted 7 lines

While I'm not defending macro abuse, please note that Daniele's problem appears to have been caused by using g++ instead of gcc or gcc -x c to compile a kernel module. Daniele's later example throws a syntax error in gcc, since the cpp output isn't legal C ...

Hence I fail to see the utility of hacking in kludges for something that's not supposed to work anyway.

Yes i confess, i'm writing a kernel module in c++ (and i'm not the only one).
Anyway my consideration was general and IMHO applies to C too. What is the benefit of redefining commonly used words? I would say nothing against eg #define _I386_current get_current(), but just #define current get_current() seems to me a little bit dangerous. What is the limit? What do you consider a bad practice? Would #define i j be tolerated?

I wouldn't like to open a discussion about using c++ for kernel modules because i know that the large majority of kernel developers is against. And in fact i had to make my own version of the kernel sources turning all 'new' into 'nEw', 'class' into 'klass' and so on, but this last problem was more subtle.

But let me at least summarize my poor-programmer-not-kernel-developer point of view: at present the kernel if a mined field for c++ and i understand it is not viable nor interesting for the majority to rewrite it in a more c++-friendly way. But why not at least keep in mind, while writing new stuff (not the case of current.h i see), that kernel headers could be included by c++?

Regards, Daniele

#9 lore raw
Quoted 6 lines · Daniele Lugli

But let me at least summarize my poor-programmer-not-kernel-developer point of view: at present the kernel if a mined field for c++ and i understand it is not viable nor interesting for the majority to rewrite it in a more c++-friendly way. But why not at least keep in mind, while writing new stuff (not the case of current.h i see), that kernel headers could be included by c++?

current.h is, indeed, a special case. #define i j would not be tolerated simply because it's stupid. Abuses of preprocessor are generally frowned upon, but there are passionate wa^H^Hpersons who just can't help themselves and use e.g. ## for no good reason.

But as for C++... frankly, for all I care it doesn't exist. As long as requirements of style happen to reduce problems of C++ programmers - they are lucky. But other than that... watch me not care. In the linux kernel context C++ is obscure language and it will stay that way. Ergo, no reasons to spend any mental efforts on being nice to it. Deal.

#10 lore raw
In reply to Daniele Lugli
Quoted 24 lines · Daniele Lugli
Quoted 15 lines · Mikael Pettersson
Quoted 6 lines · Rik van Riel
Quoted 5 lines · Chris Wedgwood
Quoted 2 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

*** one of my data structures has a field named 'current'. ***

gcc -Wshadow

Would it be a good idea to add -Wshadow to the kernel compile options by default ?

Quoted 7 lines

While I'm not defending macro abuse, please note that Daniele's problem appears to have been caused by using g++ instead of gcc or gcc -x c to compile a kernel module. Daniele's later example throws a syntax error in gcc, since the cpp output isn't legal C ...

Hence I fail to see the utility of hacking in kludges for something that's not supposed to work anyway.

Quoted 7 lines

Yes i confess, i'm writing a kernel module in c++ (and i'm not the only one).
Anyway my consideration was general and IMHO applies to C too. What is the benefit of redefining commonly used words? I would say nothing against eg #define _I386_current get_current(), but just #define current get_current() seems to me a little bit dangerous. What is the limit? What do you consider a bad practice? Would #define i j be tolerated?

As I wrote above: "While I'm not defending macro abuse". #define i j is definitely macro abuse, and no sane programmer should do it.

Any programming language has a set of reserved words, and any large piece of software has its own reserved words. Think of C++ "this" or C typedef names, for example. You don't expect new code to work if it violates the syntax of the system in which it is compiled, do you?

"current" is just that: one of the Linux kernel's reserved words, one that kernel programmers are supposed to know about.

Quoted 6 lines

But let me at least summarize my poor-programmer-not-kernel-developer point of view: at present the kernel if a mined field for c++ and i understand it is not viable nor interesting for the majority to rewrite it in a more c++-friendly way. But why not at least keep in mind, while writing new stuff (not the case of current.h i see), that kernel headers could be included by c++?

1. The kernel is not written in C++.
2. C++ is not C, and a C++ compiler is not a substitute for a C compiler.
3. User-space should't include raw kernel headers but "sanitized" ones, provided e.g. by the C library.

Ergo, the kernel headers should never be processed by a C++ compiler, and anyone doing it anyway is on their own.

/Mikael

#11 lore raw
In reply to Daniele Lugli
Quoted 9 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

*** one of my data structures has a field named 'current'. ***

Pretty common word, isn't it? Would you think it can cause such a trouble? But in some of my files I happen to indirectly include <asm/current.h> (kernel 2.4.18 for i386), containing the following line:

Quoted 6 lines

#define current get_current()

so that my structure becomes the owner of a function it has never asked for, while it looses a data member. gcc has nothing to complain about that.

This cannot be the reason for your problem. The name of a structure member has no connection whatsoever with the name of any function or definition.

The following code will correctly write "Hello world!" to the screen even though the text initializes a member of a structure called "current" while "current" has been defined to be a function called puts.

#include <stdio.h>
#define current puts

struct foo {
    char *current;
    int foo;
    } bar; 
main()
{
    bar.current = "Hello world!";
    current(bar.current);
    return 0;
}

For your code to get "confused", you really have something else wrong. That said, some name-space polution may make it difficult to find the problem. For instance, a structure member is expected to have a ";" after it. It's possible for some previous definition to make a syntax error invisible.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips). The US military has given us many words, FUBAR, SNAFU, now ENRON. Yes, top management were graduates of West Point and Annapolis.

#12 lore raw
Quoted 5 lines · Richard B. Johnson
Quoted 1 line

#define current get_current()

This cannot be the reason for your problem. The name of a structure member has no connection whatsoever with the name of any function or definition.

You forgot the effect of the parenthesis. This isn't a name-changing macro, this is a variable-to-function-call changing macro.

OG.

#13 lore raw
Quoted 12 lines · Olivier Galibert
Quoted 5 lines · Richard B. Johnson
Quoted 1 line

#define current get_current()

This cannot be the reason for your problem. The name of a structure member has no connection whatsoever with the name of any function or definition.

You forgot the effect of the parenthesis. This isn't a name-changing macro, this is a variable-to-function-call changing macro.

OG.

Yep. But if the originator can not tried to compile kernel headers with g++, an appropriate diagnostic would have been caught as shown.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips). The US military has given us many words, FUBAR, SNAFU, now ENRON. Yes, top management were graduates of West Point and Annapolis.

#15 lore raw
In reply to Richard B. Johnson
Quoted 40 lines · Richard B. Johnson
Quoted 9 lines · Daniele Lugli

I recently wrote a kernel module which gave me some mysterious problems. After too many days spent in blood, sweat and tears, I found the cause:

*** one of my data structures has a field named 'current'. ***

Pretty common word, isn't it? Would you think it can cause such a trouble? But in some of my files I happen to indirectly include <asm/current.h> (kernel 2.4.18 for i386), containing the following line:

Quoted 6 lines

#define current get_current()

so that my structure becomes the owner of a function it has never asked for, while it looses a data member. gcc has nothing to complain about that.

This cannot be the reason for your problem. The name of a structure member has no connection whatsoever with the name of any function or definition.

The following code will correctly write "Hello world!" to the screen even though the text initializes a member of a structure called "current" while "current" has been defined to be a function called puts.

#include <stdio.h>
#define current puts

struct foo {
    char *current;
    int foo;
    } bar;
main()
{
    bar.current = "Hello world!";
    current(bar.current);
    return 0;
}
Quoted 8 lines

For your code to get "confused", you really have something else wrong. That said, some name-space polution may make it difficult to find the problem. For instance, a structure member is expected to have a ";" after it. It's possible for some previous definition to make a syntax error invisible.

Cheers,
Dick Johnson

Try the following instead:

// file shade1.cpp

// excerpt from common.h

#define current get_current()

// my stuff

struct {
int any;
int current[1000];
} mine;

// file shade2.cpp

#include <stdio.h>

// my stuff

extern struct {
int any;
int current[1000];
} mine;

int main () {
mine.current[999] = 1;
printf ("%d\n", mine.current[999]);
}

g++ shade1.cpp shade2.cpp

./a.out => segmentation fault

Regards, Daniele

#16 lore raw
Quoted 33 lines · Daniele Lugli

Try the following instead:

// file shade1.cpp

// excerpt from common.h

#define current get_current()

// my stuff

struct {
int any;
int current[1000];
} mine;

// file shade2.cpp

#include <stdio.h>

// my stuff

extern struct {
int any;
int current[1000];
} mine;

int main () {
mine.current[999] = 1;
printf ("%d\n", mine.current[999]);
}

Quoted 6 lines

g++ shade1.cpp shade2.cpp

./a.out => segmentation fault

Regards, Daniele

It should have written a diagnostic which it does in C, not C++.

xxx.c:6: get_current' declared as function returning an array xxx.c:6: field get_current' declared as a function

This () make all the difference. If you are trying to write kernel drivers in C++, you will have more suprises. If not, you should not be including kernel headers.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips). The US military has given us many words, FUBAR, SNAFU, now ENRON. Yes, top management were graduates of West Point and Annapolis.

#17 lore raw
In reply to Daniele Lugli
Quoted 7 lines · Daniele Lugli

*** one of my data structures has a field named 'current'. ***

Pretty common word, isn't it? Would you think it can cause such a trouble? But in some of my files I happen to indirectly include <asm/current.h> (kernel 2.4.18 for i386), containing the following line:

#define current get_current()

How about changing the definition to:

#define current ((struct task_struct *)get_current())

That should get the same effect as currently for kernel code, but will guarantee a syntax error if it's used in a structure declaration.

-Andi

#18 lore raw
Quoted 3 lines · Andi Kleen

How about changing the definition to:

#define current ((struct task_struct *)get_current())

Is there some magic way to make it an inline function? That way collisions would be at the compiler level as opposed to the preprocessor level (pretending there is a strong separation here).

--cw