All of lore.kernel.org
 help / color / mirror / Atom feed
* Compiling C++ modules
@ 2006-04-24 19:16 Gary Poppitz
  2006-04-24 19:27 ` Greg KH
                   ` (6 more replies)
  0 siblings, 7 replies; 200+ messages in thread
From: Gary Poppitz @ 2006-04-24 19:16 UTC (permalink / raw)
  To: linux-kernel

I have the task of porting an existing file system to Linux. This  
code is in C++ and I have noticed that the Linux kernel has
made use of C++ keywords and other things that make it incompatible.

I would be most willing to point out the areas that need adjustment  
and supply patch files to be reviewed.

What would be the best procedure to accomplish this?

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
@ 2006-04-24 19:27 ` Greg KH
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
  2006-04-24 19:30 ` Compiling C++ modules Al Viro
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 200+ messages in thread
From: Greg KH @ 2006-04-24 19:27 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Mon, Apr 24, 2006 at 01:16:26PM -0600, Gary Poppitz wrote:
> I have the task of porting an existing file system to Linux. This  
> code is in C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.

We know they are "incompatible", why else would we allow "private" and
"struct class" in the kernel source if we some how expected it to work
with a C++ compiler?

Please see the lkml FAQ (linked to at the bottom of every lkml message)
for why this will not happen.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
  2006-04-24 19:27 ` Greg KH
@ 2006-04-24 19:30 ` Al Viro
  2006-04-24 19:40 ` linux-os (Dick Johnson)
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 200+ messages in thread
From: Al Viro @ 2006-04-24 19:30 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Mon, Apr 24, 2006 at 01:16:26PM -0600, Gary Poppitz wrote:
> I have the task of porting an existing file system to Linux. This  
> code is in C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.
> 
> I would be most willing to point out the areas that need adjustment  
> and supply patch files to be reviewed.
> 
> What would be the best procedure to accomplish this?

cat same_old_stuff >/dev/null and save the bandwidth...

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
  2006-04-24 19:27 ` Greg KH
  2006-04-24 19:30 ` Compiling C++ modules Al Viro
@ 2006-04-24 19:40 ` linux-os (Dick Johnson)
  2006-04-24 20:54   ` Geert Uytterhoeven
  2006-04-24 19:42 ` Alexey Dobriyan
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-24 19:40 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel


On Mon, 24 Apr 2006, Gary Poppitz wrote:

> I have the task of porting an existing file system to Linux. This
> code is in C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.
>
> I would be most willing to point out the areas that need adjustment
> and supply patch files to be reviewed.
>
> What would be the best procedure to accomplish this?

Rewrite the file-system in C. The kernel is written in 'C' and
assembly.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
Warning : 98.36% of all statistics are fiction, book release in April.
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
                   ` (2 preceding siblings ...)
  2006-04-24 19:40 ` linux-os (Dick Johnson)
@ 2006-04-24 19:42 ` Alexey Dobriyan
  2006-04-24 20:30 ` Daniel Barkalow
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 200+ messages in thread
From: Alexey Dobriyan @ 2006-04-24 19:42 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Mon, Apr 24, 2006 at 01:16:26PM -0600, Gary Poppitz wrote:
> I have the task of porting an existing file system to Linux. This
> code is in C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.
>
> I would be most willing to point out the areas that need adjustment
> and supply patch files to be reviewed.

Such patches will be rejected. This was discussed many times, go search
archives.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* C++ pushback
@ 2006-04-24 20:02   ` Gary Poppitz
  2006-04-24 20:15     ` Christoph Hellwig
                       ` (6 more replies)
  0 siblings, 7 replies; 200+ messages in thread
From: Gary Poppitz @ 2006-04-24 20:02 UTC (permalink / raw)
  To: linux-kernel

> We know they are "incompatible", why else would we allow "private" and
> "struct class" in the kernel source if we some how expected it to work
> with a C++ compiler?


I can see that this was intentional, not an oversight.

If there is a childish temper tantrum mentality about C++ then I have  
no reason or desire to be on this list.

Grow up.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
@ 2006-04-24 20:15     ` Christoph Hellwig
  2006-04-24 20:16     ` Greg KH
                       ` (5 subsequent siblings)
  6 siblings, 0 replies; 200+ messages in thread
From: Christoph Hellwig @ 2006-04-24 20:15 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Mon, Apr 24, 2006 at 02:02:27PM -0600, Gary Poppitz wrote:
> >We know they are "incompatible", why else would we allow "private" and
> >"struct class" in the kernel source if we some how expected it to work
> >with a C++ compiler?
> 
> 
> I can see that this was intentional, not an oversight.
> 
> If there is a childish temper tantrum mentality about C++ then I have  
> no reason or desire to be on this list.

so sodd off.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
  2006-04-24 20:15     ` Christoph Hellwig
@ 2006-04-24 20:16     ` Greg KH
  2006-04-24 20:18     ` Martin Mares
                       ` (4 subsequent siblings)
  6 siblings, 0 replies; 200+ messages in thread
From: Greg KH @ 2006-04-24 20:16 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Mon, Apr 24, 2006 at 02:02:27PM -0600, Gary Poppitz wrote:
> >We know they are "incompatible", why else would we allow "private" and
> >"struct class" in the kernel source if we some how expected it to work
> >with a C++ compiler?
> 
> 
> I can see that this was intentional, not an oversight.
> 
> If there is a childish temper tantrum mentality about C++ then I have  
> no reason or desire to be on this list.

If there is a lack of willingness to do a simple bit of research:
	http://www.google.com/search?q=linux+kernel+C%2B%2B
The responses you get back might seem a big harsh.

In short, the rule around here, as well with most groups in life, seems
to be:
	"show no respect, get none in return"

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
  2006-04-24 20:15     ` Christoph Hellwig
  2006-04-24 20:16     ` Greg KH
@ 2006-04-24 20:18     ` Martin Mares
  2006-04-24 21:36       ` Jeff V. Merkey
                         ` (2 more replies)
  2006-04-24 20:36     ` Thiago Galesi
                       ` (3 subsequent siblings)
  6 siblings, 3 replies; 200+ messages in thread
From: Martin Mares @ 2006-04-24 20:18 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

> If there is a childish temper tantrum mentality about C++ then I have  
> no reason or desire to be on this list.

Can you name any reasons for why should we support C++ in the kernel?
Why shouldn't we invest the effort to making it possible to write kernel
modules in Haskell instead?

The kernel is written in C and its maintainers have so far agreed that
C is enough and adding any other language brings more pain than gain.

If you think otherwise, feel free to submit some real code which shows
the advantages of using a different language.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
United Computer Wizards, Prague, Czech Republic, Europe, Earth, Universe
"C++: an octopus made by nailing extra legs onto a dog." -- Steve Taylor

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
                   ` (3 preceding siblings ...)
  2006-04-24 19:42 ` Alexey Dobriyan
@ 2006-04-24 20:30 ` Daniel Barkalow
  2006-04-24 20:35 ` C++ is in US [Re: Compiling C++ modules] Jiri Slaby
  2006-04-24 20:45 ` Compiling C++ modules Alan Cox
  6 siblings, 0 replies; 200+ messages in thread
From: Daniel Barkalow @ 2006-04-24 20:30 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Mon, 24 Apr 2006, Gary Poppitz wrote:

> I have the task of porting an existing file system to Linux. This code is in
> C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.

You probably want to look into FUSE. C++ isn't going to be supported in 
the kernel, for a variety of reasons, but filesystems don't have to be in 
the kernel these days. FUSE seems to have C++ bindings with templates and 
stuff, too, so it should be an easy task.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply	[flat|nested] 200+ messages in thread

* C++ is in US [Re: Compiling C++ modules]
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
                   ` (4 preceding siblings ...)
  2006-04-24 20:30 ` Daniel Barkalow
@ 2006-04-24 20:35 ` Jiri Slaby
  2006-04-24 20:45 ` Compiling C++ modules Alan Cox
  6 siblings, 0 replies; 200+ messages in thread
From: Jiri Slaby @ 2006-04-24 20:35 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Gary Poppitz napsal(a):
> I have the task of porting an existing file system to Linux. This code
> is in C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.
Just a though, have you considered FUSE?

regards,
- --
Jiri Slaby         www.fi.muni.cz/~xslaby
\_.-^-._   jirislaby@gmail.com   _.-^-._/
B67499670407CE62ACC8 22A032CC55C339D47A7E
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iD8DBQFETTaGMsxVwznUen4RAg53AJ4w35BylwsCSx5IWh17ebA5hV4ZHQCcCAoJ
DolwMX7+Yn2mjkIko5lXwBQ=
=CWQC
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
                       ` (2 preceding siblings ...)
  2006-04-24 20:18     ` Martin Mares
@ 2006-04-24 20:36     ` Thiago Galesi
  2006-04-24 21:38     ` Kurt Wall
                       ` (2 subsequent siblings)
  6 siblings, 0 replies; 200+ messages in thread
From: Thiago Galesi @ 2006-04-24 20:36 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

OK, let's get a couple of things clear...

No one here "hates" C++ per se. It is a tool, and every tool has its purpose.

Using C++ in the kernel has not been deemed apropriate for several
reasons. There are several (other) reasons to make the Linux Kernel C
only, this has been discussed, trolled, flamed, argued, come, gone,
etc, etc FAQs and searches are your friend there.

In your scenario, you have two possible option (IMHO)

1 - Port your existing code to C

2- keep it in C++, keep it in user level and have a simple file system
driver communicating with your existing code (I think FUSE applies to
the situation)

Thiago



On 4/24/06, Gary Poppitz <poppitzg@iomega.com> wrote:
> > We know they are "incompatible", why else would we allow "private" and
> > "struct class" in the kernel source if we some how expected it to work
> > with a C++ compiler?
>
>
> I can see that this was intentional, not an oversight.
>
> If there is a childish temper tantrum mentality about C++ then I have
> no reason or desire to be on this list.
>
> Grow up.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:16 Compiling C++ modules Gary Poppitz
                   ` (5 preceding siblings ...)
  2006-04-24 20:35 ` C++ is in US [Re: Compiling C++ modules] Jiri Slaby
@ 2006-04-24 20:45 ` Alan Cox
  2006-04-24 21:03   ` Avi Kivity
  2006-04-24 21:36   ` J.A. Magallon
  6 siblings, 2 replies; 200+ messages in thread
From: Alan Cox @ 2006-04-24 20:45 UTC (permalink / raw)
  To: Gary Poppitz; +Cc: linux-kernel

On Llu, 2006-04-24 at 13:16 -0600, Gary Poppitz wrote:
> I have the task of porting an existing file system to Linux. This  
> code is in C++ and I have noticed that the Linux kernel has
> made use of C++ keywords and other things that make it incompatible.

We tried various things involving C++ along the line in kernel history
and there are so many problems it throws up the kernel took the view
that it would not use C++ in kernel. Instead object orientation is
performed more explicitly in C. This has many advantages including the
exposure of inefficient code explicitly and the avoidance of exceptions
and the assumption memory allocations just don't fail that much C++
makes without exceptions being used. It might be possible to move to a
strict C++ subset in the style of Apple but there isn't much interest in
this.

There are other problems too, notably the binary ABI between the C and C
++ compiler might not match for all cases (in particular there are
corner cases with zero sized objects and C++).


> I would be most willing to point out the areas that need adjustment  
> and supply patch files to be reviewed.
> 
> What would be the best procedure to accomplish this?

If you want to maintain your own out of tree file system then probably
you want to use #defines to wrap the kernel tree. Most stuff will
probably work ok if you do this although you'll want some C to C++
wrappers to interface to the kernel obviously.

If you want to submit the file system to the kernel source then it needs
shifting from C++ to C but of course there are people in the community
who can help you. As the kernel C is very object based that isn't
usually too much of a problem. Most objects in the kernel (inodes, files
etc) are of the form

	struct thing {
		struct thing_ops *ops; /* methods */
		blah
	}

and that style fits much C++ code being ported over.

There are a few anti C++ bigots around too, but the kernel choice of C
was based both on rational choices and experimentation early on with the
C++ compiler.

Alan


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 19:40 ` linux-os (Dick Johnson)
@ 2006-04-24 20:54   ` Geert Uytterhoeven
  0 siblings, 0 replies; 200+ messages in thread
From: Geert Uytterhoeven @ 2006-04-24 20:54 UTC (permalink / raw)
  To: linux-os (Dick Johnson); +Cc: Gary Poppitz, Linux Kernel Development

On Mon, 24 Apr 2006, linux-os (Dick Johnson) wrote:
> On Mon, 24 Apr 2006, Gary Poppitz wrote:
> > I have the task of porting an existing file system to Linux. This
> > code is in C++ and I have noticed that the Linux kernel has
> > made use of C++ keywords and other things that make it incompatible.
> >
> > I would be most willing to point out the areas that need adjustment
> > and supply patch files to be reviewed.
> >
> > What would be the best procedure to accomplish this?
> 
> Rewrite the file-system in C. The kernel is written in 'C' and
> assembly.

Preferably C, unless you want to code for +20 architectures in parallel ;-)

> to DeliveryErrors@analogic.com - and destroy all copies of this information,
> including any attachments, without reading or disclosing them.

Aarghl, again I forgot lawyers read from bottom to top...

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 20:45 ` Compiling C++ modules Alan Cox
@ 2006-04-24 21:03   ` Avi Kivity
  2006-04-24 21:23     ` Joshua Hudson
                       ` (5 more replies)
  2006-04-24 21:36   ` J.A. Magallon
  1 sibling, 6 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-24 21:03 UTC (permalink / raw)
  To: Alan Cox; +Cc: Gary Poppitz, linux-kernel

Alan Cox wrote:
> There are a few anti C++ bigots around too, but the kernel choice of C
> was based both on rational choices and experimentation early on with the
> C++ compiler.
>   
Times have changed, though. The C++ compiler is much better now, and the 
recent slew of error handling bugs shows that C is a very unsafe language.

I think it's easy to show that the equivalent C++ code would be shorter, 
faster, and safer.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:03   ` Avi Kivity
@ 2006-04-24 21:23     ` Joshua Hudson
  2006-04-24 21:29     ` Kyle Moffett
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 200+ messages in thread
From: Joshua Hudson @ 2006-04-24 21:23 UTC (permalink / raw)
  To: Avi Kivity, linux-kernel

>Do not meddle in the internals of kernels, for they are subtle and
quick to panic.
Ha ha. Quick to OOPS maybe, but it keeps running after that more often than not.
I've gotten a clean shutdown after null pointer exception while
holding several locks.
Thank goodness for preemptable kernel.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 21:36       ` Jeff V. Merkey
@ 2006-04-24 21:28         ` J.A. Magallon
  2006-04-24 21:43           ` Harald Arnesen
  2006-04-24 21:52         ` Alan Cox
  1 sibling, 1 reply; 200+ messages in thread
From: J.A. Magallon @ 2006-04-24 21:28 UTC (permalink / raw)
  To: Jeff V. Merkey; +Cc: Martin Mares, Gary Poppitz, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 764 bytes --]

On Mon, 24 Apr 2006 15:36:50 -0600, "Jeff V. Merkey" <jmerkey@wolfmountaingroup.com> wrote:

Ahhh, I use to trash this discussions until I see something like this...

> Martin Mares wrote:
> 
> All of the hidden memory allocations from constructor/destructor 
> operatings can and do KILL OS PERFORMANCE.

FUD. Learn to write C++.

> Java
> is a great example as to why kernel OS code should NEVER be allowed in C++.
> 

Java and C++ are like apples and oranges.

--
J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
werewolf!able!es                         \         It's better when it's free
Mandriva Linux release 2006.1 (Cooker) for i586
Linux 2.6.16-jam9 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Tue

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:03   ` Avi Kivity
  2006-04-24 21:23     ` Joshua Hudson
@ 2006-04-24 21:29     ` Kyle Moffett
  2006-04-24 21:50       ` marty fouts
  2006-04-25  7:08       ` Avi Kivity
  2006-04-24 21:58     ` Alan Cox
                       ` (3 subsequent siblings)
  5 siblings, 2 replies; 200+ messages in thread
From: Kyle Moffett @ 2006-04-24 21:29 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Alan Cox, Gary Poppitz, linux-kernel

On Apr 24, 2006, at 17:03:46, Avi Kivity wrote:
> Alan Cox wrote:
>> There are a few anti C++ bigots around too, but the kernel choice  
>> of C was based both on rational choices and experimentation early  
>> on with the C++ compiler.
>
> Times have changed, though. The C++ compiler is much better now,  
> and the recent slew of error handling bugs shows that C is a very  
> unsafe language.
>
> I think it's easy to show that the equivalent C++ code would be  
> shorter, faster, and safer.

Really?  What features exactly does C++ have over C that you think  
make that true?  Implicit memory allocation? Exceptions?  Operator  
overloading?  Tendency to use StudlyCaps?  What else can C++ do that  
C can not?

For example, I could write the following:

class Foo {
public:
	Foo() { /* ... init code ... */ }
	~Foo() { /* ... free code ... */ }
	int do_thing(int arg) { /* ... code ... */ }

private:
	int data_member;
};

Or I could write it like this:

struct foo {
	int data_member;
};

int foo_init() { /* ... init code ... */ }
int foo_destroy() { /* ... free code ... */ }
int foo_do_thing(int arg) { /* ... code ... */ }


The "advantages" of the former over the latter:

(1)  Without exceptions (which are fragile in a kernel), the former  
can't return an error instead of initializing the Foo.

(2)  You can't control when you initialize the Foo.  For example in  
this code, the "Foo item;" declarations seem to be trivially  
relocatable, even if they're not.
     spin_lock(&foo_lock);
     Foo item1;
     Foo item2;
     spin_unlock(&foo_lock);

(3)  Foo could theoretically implement overloaded operators.  How  
exactly is it helpful to do math on structs?  Does that actually make  
it any easier to understand the code?  How does it make it more  
obvious to be able to write a "+" operator that allocates memory?


Cheers,
Kyle Moffett


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 20:45 ` Compiling C++ modules Alan Cox
  2006-04-24 21:03   ` Avi Kivity
@ 2006-04-24 21:36   ` J.A. Magallon
  1 sibling, 0 replies; 200+ messages in thread
From: J.A. Magallon @ 2006-04-24 21:36 UTC (permalink / raw)
  To: Alan Cox; +Cc: Gary Poppitz, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1341 bytes --]

On Mon, 24 Apr 2006 21:45:46 +0100, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> makes without exceptions being used. It might be possible to move to a
> strict C++ subset in the style of Apple but there isn't much interest in
> this.
>

Probably there will be two fields where a subset of C++ would give a big
save to the kernel:
- All that 'hand-coded' object orientation ans inheritance makes tons of
  structs repeating function pointers and the like, and using tricky
  rules to be sure nobody creates a class without a pure virtual method
  (funtion pointer). Binary space.
- You are doing in source code what the compiler should do for you.

> There are other problems too, notably the binary ABI between the C and C
> ++ compiler might not match for all cases (in particular there are
> corner cases with zero sized objects and C++).
>

There is no point in interfaccing C and C++. But a full C++-subset kernel
would be equally fast and probably safer to write code for that this.

But things are like they are. Kernel is C.

--
J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
werewolf!able!es                         \         It's better when it's free
Mandriva Linux release 2006.1 (Cooker) for i586
Linux 2.6.16-jam9 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Tue

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:18     ` Martin Mares
@ 2006-04-24 21:36       ` Jeff V. Merkey
  2006-04-24 21:28         ` J.A. Magallon
  2006-04-24 21:52         ` Alan Cox
  2006-04-24 23:02       ` David Schwartz
  2006-04-25  7:33       ` Avi Kivity
  2 siblings, 2 replies; 200+ messages in thread
From: Jeff V. Merkey @ 2006-04-24 21:36 UTC (permalink / raw)
  To: Martin Mares; +Cc: Gary Poppitz, linux-kernel

Martin Mares wrote:

>>If there is a childish temper tantrum mentality about C++ then I have  
>>no reason or desire to be on this list.
>>    
>>
>
>Can you name any reasons for why should we support C++ in the kernel?
>Why shouldn't we invest the effort to making it possible to write kernel
>modules in Haskell instead?
>
>The kernel is written in C and its maintainers have so far agreed that
>C is enough and adding any other language brings more pain than gain.
>
>If you think otherwise, feel free to submit some real code which shows
>the advantages of using a different language.
>
>				Have a nice fortnight
>  
>
C++ in the kernel is a BAD IDEA. C++ code can be written in such a 
convoluted manner as to be unmaintainable and unreadable.
All of the hidden memory allocations from constructor/destructor 
operatings can and do KILL OS PERFORMANCE. Java
is a great example as to why kernel OS code should NEVER be allowed in C++.

C and C++ really show their origins when used in kernel level 
programming. So what were C and C++ originally -- they were grades. :-)

I applaud the LKML folks pushing back on C++.

A++.

Jeff




^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
                       ` (3 preceding siblings ...)
  2006-04-24 20:36     ` Thiago Galesi
@ 2006-04-24 21:38     ` Kurt Wall
  2006-04-27 16:17     ` Roman Kononov
  2006-04-27 22:09     ` Bill Davidsen
  6 siblings, 0 replies; 200+ messages in thread
From: Kurt Wall @ 2006-04-24 21:38 UTC (permalink / raw)
  To: linux-kernel

On Mon, Apr 24, 2006 at 02:02:27PM -0600, Gary Poppitz took 17 lines to write:
> >We know they are "incompatible", why else would we allow "private" and
> >"struct class" in the kernel source if we some how expected it to work
> >with a C++ compiler?
> 
> 
> I can see that this was intentional, not an oversight.

If you can see it was intentional, I'm baffled why it didn't occur to you
to do some simple research before posting or even trouble yourself to
ask "Why?" on LKML.

> If there is a childish temper tantrum mentality about C++ then I have  
> no reason or desire to be on this list.

If there is an unwillingness to learn the ground rules and conventions
of the group you want to join, then the group has no reason nor desire
to have you join.

> Grow up.

Bye now.

Kurt
-- 
Wit, n.:
	The salt with which the American Humorist spoils his cookery
... by leaving it out.
		-- Ambrose Bierce, "The Devil's Dictionary"

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 21:28         ` J.A. Magallon
@ 2006-04-24 21:43           ` Harald Arnesen
  0 siblings, 0 replies; 200+ messages in thread
From: Harald Arnesen @ 2006-04-24 21:43 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Jeff V. Merkey, Martin Mares, Gary Poppitz, linux-kernel

"J.A. Magallon" <jamagallon@able.es> writes:

>> Java
>> is a great example as to why kernel OS code should NEVER be allowed in C++.
>> 
>
> Java and C++ are like apples and oranges.

Fruity :-)
-- 
Hilsen Harald.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:29     ` Kyle Moffett
@ 2006-04-24 21:50       ` marty fouts
  2006-04-24 22:09         ` Martin Mares
  2006-04-25 15:32         ` Michael Buesch
  2006-04-25  7:08       ` Avi Kivity
  1 sibling, 2 replies; 200+ messages in thread
From: marty fouts @ 2006-04-24 21:50 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: linux-kernel

On 4/24/06, Kyle Moffett <mrmacman_g4@mac.com> wrote:

> What else can C++ do that C can not?

Inheritance, templates...

I would never argue in favor of converting any large existing
application, especially the Linux kernel, from C to C++ by introducing
C++ into part of it; for a lot of reasons, but it is possible to write
a reasonable OS kernel in C++ and take advantage of "C++ as a safer C"
(Koenig) to write clearer, shorter code in a lot of instances.

Unfortunately, it's almost as easy to write bad C++ as it is to write
bad C (Fortran in any language) but we (the community) have a lot more
experience in writing C kernels, so we're more familiar with how to
avoid bad C than we are with how to avoid bad C++.

The existance of Bulwer-Lytton does not disprove that good prose can
be written in English, nor does silly abuse of overloading disprove
that good code can be written in C++.

Oh, and yeah, a = b + c *is* more readable than

a = malloc(strlen(b) + strlen(c));
strcpy(a,b);
strcat(a,c);

and contains fewer bugs ;)

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 21:36       ` Jeff V. Merkey
  2006-04-24 21:28         ` J.A. Magallon
@ 2006-04-24 21:52         ` Alan Cox
  2006-04-24 22:16           ` J.A. Magallon
                             ` (2 more replies)
  1 sibling, 3 replies; 200+ messages in thread
From: Alan Cox @ 2006-04-24 21:52 UTC (permalink / raw)
  To: Jeff V. Merkey; +Cc: Martin Mares, Gary Poppitz, linux-kernel

On Llu, 2006-04-24 at 15:36 -0600, Jeff V. Merkey wrote:
> C++ in the kernel is a BAD IDEA. C++ code can be written in such a 
> convoluted manner as to be unmaintainable and unreadable.

So can C. 

> All of the hidden memory allocations from constructor/destructor 
> operatings can and do KILL OS PERFORMANCE. 

This is one area of concern. Just as big a problem for the OS case is
that the hidden constructors/destructors may fail. You can write C++
code carefully to avoid these things but it can be hard to see where the
problem is when you miss one.

C at least makes it verbose, but we trade that for poorer typechecking
and visibility control.

Alan


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:03   ` Avi Kivity
  2006-04-24 21:23     ` Joshua Hudson
  2006-04-24 21:29     ` Kyle Moffett
@ 2006-04-24 21:58     ` Alan Cox
  2006-04-25  7:20       ` Avi Kivity
  2006-04-25  4:17     ` Martin J. Bligh
                       ` (2 subsequent siblings)
  5 siblings, 1 reply; 200+ messages in thread
From: Alan Cox @ 2006-04-24 21:58 UTC (permalink / raw)
  To: Avi Kivity; +Cc: linux-kernel

On Maw, 2006-04-25 at 00:03 +0300, Avi Kivity wrote:
> Alan Cox wrote:
> I think it's easy to show that the equivalent C++ code would be shorter, 
> faster, and safer.

I've removed the poor guy from Iomega from the followups, perhaps others
could do likewise

Mathematically the answer is "no you couldn't". You might be able to
argue that a fortran implementation would be faster but not a C++ one.

And for strings C++ strings are suprisingly inefficient and need a lot
of memory allocations, which can fail and are not handled well without C
++ exceptions and other joyous language features you don't want in a
kernel. C with 'safe' string handling is similar - look at glib.

We have to make tradeoffs and the kernel tradeoffs have been to keep C
type fast string handling but to provide helpers in the hope people will
actually use them to avoid making mistakes.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:50       ` marty fouts
@ 2006-04-24 22:09         ` Martin Mares
  2006-04-24 22:30           ` Willy Tarreau
                             ` (2 more replies)
  2006-04-25 15:32         ` Michael Buesch
  1 sibling, 3 replies; 200+ messages in thread
From: Martin Mares @ 2006-04-24 22:09 UTC (permalink / raw)
  To: marty fouts; +Cc: Kyle Moffett, linux-kernel

Hello!

> Oh, and yeah, a = b + c *is* more readable than
> 
> a = malloc(strlen(b) + strlen(c));
> strcpy(a,b);
> strcat(a,c);
> 
> and contains fewer bugs ;)

Actually, it contains at least the bug you have made in your C example,
that is forgetting that malloc() can fail. So can string addition, if
allocated dynamically.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"This quote has been selected randomly. Really." -- M. Ulrichs

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 21:52         ` Alan Cox
@ 2006-04-24 22:16           ` J.A. Magallon
  2006-04-25  0:05             ` Harald Arnesen
                               ` (5 more replies)
  2006-04-24 22:39           ` Willy Tarreau
  2006-04-24 22:57           ` Jeff V. Merkey
  2 siblings, 6 replies; 200+ messages in thread
From: J.A. Magallon @ 2006-04-24 22:16 UTC (permalink / raw)
  To: Alan Cox, Linux-Kernel, 

[-- Attachment #1: Type: text/plain, Size: 1397 bytes --]

On Mon, 24 Apr 2006 22:52:12 +0100, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> On Llu, 2006-04-24 at 15:36 -0600, Jeff V. Merkey wrote:
> > C++ in the kernel is a BAD IDEA. C++ code can be written in such a 
> > convoluted manner as to be unmaintainable and unreadable.
> 
> So can C. 
> 
> > All of the hidden memory allocations from constructor/destructor 
> > operatings can and do KILL OS PERFORMANCE. 
> 
> This is one area of concern. Just as big a problem for the OS case is
> that the hidden constructors/destructors may fail.

Tell me what is the difference between:


    sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
    if (!sbi)
        return -ENOMEM;
    sb->s_fs_info = sbi;
    memset(sbi, 0, sizeof(*sbi));
    sbi->s_mount_opt = 0;
    sbi->s_resuid = EXT3_DEF_RESUID;
    sbi->s_resgid = EXT3_DEF_RESGID;

and

    SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
    {}

    ...
    sbi = new SuperBlock;
    if (!sbi)
        return -ENOMEM;

apart that you don't get members initalized twice and get a shorter code :).

--
J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
werewolf!able!es                         \         It's better when it's free
Mandriva Linux release 2006.1 (Cooker) for i586
Linux 2.6.16-jam9 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Tue

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 22:09         ` Martin Mares
@ 2006-04-24 22:30           ` Willy Tarreau
  2006-04-24 22:32           ` Joshua Hudson
  2006-04-24 22:45           ` marty fouts
  2 siblings, 0 replies; 200+ messages in thread
From: Willy Tarreau @ 2006-04-24 22:30 UTC (permalink / raw)
  To: Martin Mares; +Cc: marty fouts, Kyle Moffett, linux-kernel

On Tue, Apr 25, 2006 at 12:09:01AM +0200, Martin Mares wrote:
> Hello!
> 
> > Oh, and yeah, a = b + c *is* more readable than
> > 
> > a = malloc(strlen(b) + strlen(c));
> > strcpy(a,b);
> > strcat(a,c);
> > 
> > and contains fewer bugs ;)
> 
> Actually, it contains at least the bug you have made in your C example,
> that is forgetting that malloc() can fail. So can string addition, if
> allocated dynamically.

And if it does not fail, it may overflow because he forgot one char in
the malloc(). Anyway, I still prefer the C form, at least I know what
it does.

Cheers,
Willy


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 22:09         ` Martin Mares
  2006-04-24 22:30           ` Willy Tarreau
@ 2006-04-24 22:32           ` Joshua Hudson
  2006-04-24 22:45           ` marty fouts
  2 siblings, 0 replies; 200+ messages in thread
From: Joshua Hudson @ 2006-04-24 22:32 UTC (permalink / raw)
  To: linux-kernel

On 4/24/06, Martin Mares <mj@ucw.cz> wrote:
> Hello!
>
> > Oh, and yeah, a = b + c *is* more readable than
> >
> > a = malloc(strlen(b) + strlen(c));
> > strcpy(a,b);
> > strcat(a,c);
> >
> > and contains fewer bugs ;)
>
> Actually, it contains at least the bug you have made in your C example,
> that is forgetting that malloc() can fail. So can string addition, if
> allocated dynamically.
>
>                                 Have a nice fortnight
The C++ code *still* contains fewer bugs. I didn't see the malloc() one, but
there is another.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 21:52         ` Alan Cox
  2006-04-24 22:16           ` J.A. Magallon
@ 2006-04-24 22:39           ` Willy Tarreau
  2006-04-24 22:57           ` Jeff V. Merkey
  2 siblings, 0 replies; 200+ messages in thread
From: Willy Tarreau @ 2006-04-24 22:39 UTC (permalink / raw)
  To: Alan Cox; +Cc: Jeff V. Merkey, Martin Mares, Gary Poppitz, linux-kernel

On Mon, Apr 24, 2006 at 10:52:12PM +0100, Alan Cox wrote:
> On Llu, 2006-04-24 at 15:36 -0600, Jeff V. Merkey wrote:
> > C++ in the kernel is a BAD IDEA. C++ code can be written in such a 
> > convoluted manner as to be unmaintainable and unreadable.
> 
> So can C. 
> 
> > All of the hidden memory allocations from constructor/destructor 
> > operatings can and do KILL OS PERFORMANCE. 
> 
> This is one area of concern. Just as big a problem for the OS case is
> that the hidden constructors/destructors may fail. You can write C++
> code carefully to avoid these things but it can be hard to see where the
> problem is when you miss one.

Not counting the compiler bugs. When you see how the kernel tends to
trigger gcc bugs on which people spend a lot of time, I wouldn't want
to be the guy trying to identify bad code generation in C++...

Cheers,
Willy


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 22:09         ` Martin Mares
  2006-04-24 22:30           ` Willy Tarreau
  2006-04-24 22:32           ` Joshua Hudson
@ 2006-04-24 22:45           ` marty fouts
  2 siblings, 0 replies; 200+ messages in thread
From: marty fouts @ 2006-04-24 22:45 UTC (permalink / raw)
  To: Martin Mares; +Cc: Kyle Moffett, linux-kernel

On 4/24/06, Martin Mares <mj@ucw.cz> wrote:
> Hello!
>
> > Oh, and yeah, a = b + c *is* more readable than
> >
> > a = malloc(strlen(b) + strlen(c));
> > strcpy(a,b);
> > strcat(a,c);
> >
> > and contains fewer bugs ;)
>
> Actually, it contains at least the bug you have made in your C example,
> that is forgetting that malloc() can fail. So can string addition, if
> allocated dynamically.

It's too small of a fragment to tell whether or not appropriate
exception handling has been set up, but yeah, it needs a try/catch to
be safe.  That's *1* of the bugs in the c example.  It's the one they
share.

It's not the only one in the C code, though, as Willy Tarreau pointed
out, the malloc idiom is wrong, since it doesn't allocate space for
the terminating null.

Of course, the C fragment has the implicit problem of who will do the
associated free to avoid the memory leak, where the C++ fragment has
the issue of garbage collection...

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 21:52         ` Alan Cox
  2006-04-24 22:16           ` J.A. Magallon
  2006-04-24 22:39           ` Willy Tarreau
@ 2006-04-24 22:57           ` Jeff V. Merkey
  2 siblings, 0 replies; 200+ messages in thread
From: Jeff V. Merkey @ 2006-04-24 22:57 UTC (permalink / raw)
  To: Alan Cox; +Cc: Martin Mares, Gary Poppitz, linux-kernel

Alan Cox wrote:

>On Llu, 2006-04-24 at 15:36 -0600, Jeff V. Merkey wrote:
>  
>
>>C++ in the kernel is a BAD IDEA. C++ code can be written in such a 
>>convoluted manner as to be unmaintainable and unreadable.
>>    
>>
>
>So can C. 
>
>  
>
>>All of the hidden memory allocations from constructor/destructor 
>>operatings can and do KILL OS PERFORMANCE. 
>>    
>>
>
>This is one area of concern. Just as big a problem for the OS case is
>that the hidden constructors/destructors may fail. You can write C++
>code carefully to avoid these things but it can be hard to see where the
>problem is when you miss one.
>
>C at least makes it verbose, but we trade that for poorer typechecking
>and visibility control.
>
>Alan
>  
>

Yep.

Jeff

>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/
>
>  
>


^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-24 20:18     ` Martin Mares
  2006-04-24 21:36       ` Jeff V. Merkey
@ 2006-04-24 23:02       ` David Schwartz
  2006-04-25  8:55         ` Martin Mares
  2006-04-25  7:33       ` Avi Kivity
  2 siblings, 1 reply; 200+ messages in thread
From: David Schwartz @ 2006-04-24 23:02 UTC (permalink / raw)
  To: Linux-Kernel@Vger. Kernel. Org


> Can you name any reasons for why should we support C++ in the kernel?
> Why shouldn't we invest the effort to making it possible to write kernel
> modules in Haskell instead?

	I don't recall anyone asking you to so much as lift a finger. Feel free to
invest your effort where you feel it will do the most good, and try not to
criticize others for doing the same with their own resources.

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 22:16           ` J.A. Magallon
@ 2006-04-25  0:05             ` Harald Arnesen
  2006-04-25  0:46               ` Diego Calleja
  2006-04-25  1:30             ` linux-os (Dick Johnson)
                               ` (4 subsequent siblings)
  5 siblings, 1 reply; 200+ messages in thread
From: Harald Arnesen @ 2006-04-25  0:05 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Alan Cox, Linux-Kernel, 

"J.A. Magallon" <jamagallon@able.es> writes:

> Tell me what is the difference between:
>
>
>     sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
>     if (!sbi)
>         return -ENOMEM;
>     sb->s_fs_info = sbi;
>     memset(sbi, 0, sizeof(*sbi));
>     sbi->s_mount_opt = 0;
>     sbi->s_resuid = EXT3_DEF_RESUID;
>     sbi->s_resgid = EXT3_DEF_RESGID;
>
> and
>
>     SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>     {}
>
>     ...
>     sbi = new SuperBlock;
>     if (!sbi)
>         return -ENOMEM;
>
> apart that you don't get members initalized twice and get a shorter code :).

The former is easier to read and understand?
-- 
Hilsen Harald.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  0:05             ` Harald Arnesen
@ 2006-04-25  0:46               ` Diego Calleja
  2006-04-25  9:12                 ` Harald Arnesen
  0 siblings, 1 reply; 200+ messages in thread
From: Diego Calleja @ 2006-04-25  0:46 UTC (permalink / raw)
  To: Harald Arnesen; +Cc: jamagallon, alan, linux-kernel

El Tue, 25 Apr 2006 02:05:29 +0200,
Harald Arnesen <harald@skogtun.org> escribió:

> The former is easier to read and understand?

C is not perfect, it could very well get a bit improved so it helps to make 
the code more readable, etc (and I mean: just improvements, not "lets try to
turn C into a OO language"). That however requires modifying the current
C standards, gcc...

But that doesn't justifies adding C++ support to the kernel.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 22:16           ` J.A. Magallon
  2006-04-25  0:05             ` Harald Arnesen
@ 2006-04-25  1:30             ` linux-os (Dick Johnson)
  2006-04-25  2:58               ` marty fouts
  2006-04-27 22:55               ` Bill Davidsen
  2006-04-25  8:15             ` Xavier Bestel
                               ` (3 subsequent siblings)
  5 siblings, 2 replies; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-25  1:30 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Alan Cox, Linux-Kernel, 


On Mon, 24 Apr 2006, J.A. Magallon wrote:

> On Mon, 24 Apr 2006 22:52:12 +0100, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>
>> On Llu, 2006-04-24 at 15:36 -0600, Jeff V. Merkey wrote:
>>> C++ in the kernel is a BAD IDEA. C++ code can be written in such a
>>> convoluted manner as to be unmaintainable and unreadable.
>>
>> So can C.
>>
>>> All of the hidden memory allocations from constructor/destructor
>>> operatings can and do KILL OS PERFORMANCE.
>>
>> This is one area of concern. Just as big a problem for the OS case is
>> that the hidden constructors/destructors may fail.
>
> Tell me what is the difference between:
>
>
>    sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
>    if (!sbi)
>        return -ENOMEM;
>    sb->s_fs_info = sbi;
>    memset(sbi, 0, sizeof(*sbi));
>    sbi->s_mount_opt = 0;
>    sbi->s_resuid = EXT3_DEF_RESUID;
>    sbi->s_resgid = EXT3_DEF_RESGID;
>
> and
>
>    SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>    {}
>
>    ...
>    sbi = new SuperBlock;
>    if (!sbi)
>        return -ENOMEM;
>
> apart that you don't get members initalized twice and get a shorter code :).
>
> --
> J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
> werewolf!able!es                         \         It's better when it's free
> Mandriva Linux release 2006.1 (Cooker) for i586
> Linux 2.6.16-jam9 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Tue
>

I'd like to write modules in FORTRAN, myself. Unless you have been
writing software since computers were programmed with diode-pins, one
tends to think that the first programming language learned is the
best. It's generally because they are all bad, and once you learn how
to make the defective language do what you want, you tend to identify
with it. Identifying with one's captors, the Stockholm syndrome,
that's what these languages cause.

But, a master carpenter has many tools. He chooses the best for each
task. When you need to make computer hardware do what you want, in
a defined manner, in the particular order in which you require,
you use assembly language to generate the exact machine-code required.
It is possible to compromise a bit and use a slightly higher-level
procedural language called C. One loses control of everything with
any other language. Note that before C was invented, all operating
system code was written in assembly.

C++ wasn't written for this kind of work. It was written so that a
programmer didn't have to care how something was done only that somehow
it would get done. Also, as you peel away the onion skins from many
C++ graphics libraries, you find inside the core that does the work.
It's usually written in C.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
Warning : 98.36% of all statistics are fiction, book release in April.
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  1:30             ` linux-os (Dick Johnson)
@ 2006-04-25  2:58               ` marty fouts
  2006-04-27 22:55               ` Bill Davidsen
  1 sibling, 0 replies; 200+ messages in thread
From: marty fouts @ 2006-04-25  2:58 UTC (permalink / raw)
  To: linux-os (Dick Johnson); +Cc: Linux-Kernel,

On 4/24/06, linux-os (Dick Johnson) <linux-os@analogic.com> wrote:

> It is possible to compromise a bit and use a slightly higher-level
> procedural language called C. One loses control of everything with
> any other language. Note that before C was invented, all operating
> system code was written in assembly.

Even if by "operating system" you mean kernel,  this turns out not to
be true. Operating systems written in other 'moderate-level' languages
such as Fortran predate C.  (Once upon a time, a company called Pr1me
had an OS called PrimeOS, written in Fortran.)

My all time favorite OS, RSTS/E, was largely written in a Dec variant
of BASIC, called BASIC-PLUS.

High level languages  have been invented just for writing OSes (BLISS)
and OSes have been successfully written in a LISP,  PL/1, and even
C++. The last OS I worked on was almost entirely in C++ and worked ok.

What you don't want to do is add a new language to a system that was
largely written in another language. It's tempting to add C++ to a
large C system because C and C++ are similar, but it's almost always a
disaster, because you organize large systems much differently if you
design them for C++.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:03   ` Avi Kivity
                       ` (2 preceding siblings ...)
  2006-04-24 21:58     ` Alan Cox
@ 2006-04-25  4:17     ` Martin J. Bligh
  2006-04-25  5:30       ` Avi Kivity
  2006-04-25  7:56     ` Jakob Oestergaard
  2006-04-25  9:03     ` Jan Engelhardt
  5 siblings, 1 reply; 200+ messages in thread
From: Martin J. Bligh @ 2006-04-25  4:17 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Alan Cox, linux-kernel

Avi Kivity wrote:
> Alan Cox wrote:
> 
>> There are a few anti C++ bigots around too, but the kernel choice of C
>> was based both on rational choices and experimentation early on with the
>> C++ compiler.
> 
> Times have changed, though. The C++ compiler is much better now, and the 
> recent slew of error handling bugs shows that C is a very unsafe language.
> 
> I think it's easy to show that the equivalent C++ code would be shorter, 
> faster, and safer.

So ... what exactly are you waiting for? We await the results with
baited breath. This slick C++ kernel of which you speak can surely
not be far away.

M.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25  4:17     ` Martin J. Bligh
@ 2006-04-25  5:30       ` Avi Kivity
  2006-04-25  8:58         ` Sam Ravnborg
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  5:30 UTC (permalink / raw)
  To: Martin J. Bligh; +Cc: Alan Cox, linux-kernel

Martin J. Bligh wrote:
>
> So ... what exactly are you waiting for? We await the results with
> baited breath. This slick C++ kernel of which you speak can surely
> not be far away.
>
I'll start on converting 2.6.16 tomorrow, since you're anticipating it 
with such eagerness. I expect it to take some days. But a few years ago 
I did convert a filesystem in C to C++. The code was shorter, faster, 
and more robust. Fast enough to take the top position in SPEC SFS, and 
robust enough to handle the disks being pulled from under its feet 
(which a very popular Linux filesystem written in C could not at the 
time, and maybe today).

The speed benefits were largely due to algorithmic improvements, not 
language micro-optimizations; however I do claim that C++ allowed much 
faster refactoring, so we could focus our efforts on algorithms instead 
of finding our way in ever-more-convoluted error paths.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:29     ` Kyle Moffett
  2006-04-24 21:50       ` marty fouts
@ 2006-04-25  7:08       ` Avi Kivity
  2006-04-25 10:23         ` James Courtier-Dutton
  2006-04-25 15:59         ` Kyle Moffett
  1 sibling, 2 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  7:08 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Alan Cox, linux-kernel

[de-cc'ed original poster, he's far away by now]

Kyle Moffett wrote:
> On Apr 24, 2006, at 17:03:46, Avi Kivity wrote:
>> Alan Cox wrote:
>>> There are a few anti C++ bigots around too, but the kernel choice of 
>>> C was based both on rational choices and experimentation early on 
>>> with the C++ compiler.
>>
>> Times have changed, though. The C++ compiler is much better now, and 
>> the recent slew of error handling bugs shows that C is a very unsafe 
>> language.
>>
>> I think it's easy to show that the equivalent C++ code would be 
>> shorter, faster, and safer.
>
> Really?  What features exactly does C++ have over C that you think 
> make that true?  Implicit memory allocation? Exceptions?  Operator 
> overloading?  Tendency to use StudlyCaps?  What else can C++ do that C 
> can not?
>
> For example, I could write the following:
>
> class Foo {
> public:
>     Foo() { /* ... init code ... */ }
>     ~Foo() { /* ... free code ... */ }
>     int do_thing(int arg) { /* ... code ... */ }
>
> private:
>     int data_member;
> };
>
> Or I could write it like this:
>
> struct foo {
>     int data_member;
> };
>
> int foo_init() { /* ... init code ... */ }
> int foo_destroy() { /* ... free code ... */ }
> int foo_do_thing(int arg) { /* ... code ... */ }
>
>
> The "advantages" of the former over the latter:
>
> (1)  Without exceptions (which are fragile in a kernel), the former 
> can't return an error instead of initializing the Foo.
Don't discount exceptions so fast. They're exactly what makes the code 
clearer and more robust.

A very large proportion of error handling consists of:
- detect the error
- undo local changes (freeing memory and unlocking spinlocks)
- propagate the error

Exceptions make that fully automatic. The kernel uses a mix of gotos and 
alternate returns which bloat the code and are incredibly error prone. 
See the recent 2.6.16.x for examples.
>
> (2)  You can't control when you initialize the Foo.  For example in 
> this code, the "Foo item;" declarations seem to be trivially 
> relocatable, even if they're not.
>     spin_lock(&foo_lock);
>     Foo item1;
>     Foo item2;
>     spin_unlock(&foo_lock);
They only seem relocatable with your C glasses on. Put on your C++ 
glasses (much thicker), and initialization no longer seems trivially 
movable.

On the other hand, you can replace the C code

{
    Foo item1, item2;
    int r;

    spin_lock(&foo_lock);
    if ((r = foo_init(&item1)) < 0) {
        spin_unlock(&foo_lock);
        return r;
    }
    if ((r = foo_init(&item2)) < 0) {
        foo_destroy(&item1);
        spin_unlock(&foo_lock);
        return r;
    }
    foo_destroy(&item2);
    foo_destroy(&item1);
    spin_unlock(&foo_lock);
    return 0;
}

with

{
    spinlock_t::guard foo_guard(foo_lock);
    Foo item1;
    Foo item2;
}

14 lines vs 3, one variable eliminated. How many potential security 
vulnerabilities? How much time freed to work on the algorithm/data 
structure, not on error handling?
>
> (3)  Foo could theoretically implement overloaded operators.  How 
> exactly is it helpful to do math on structs?
It isn't. It's nice for other application domains (matrix algebra, etc.) 
not for kernels.

This mailing list has a full complement of reviewers who can detect 
trailing whitespace in a dark room three miles away. Surely they can 
spot an attempt to sneak in the "operator" keyword.
> Does that actually make it any easier to understand the code?  How 
> does it make it more obvious to be able to write a "+" operator that 
> allocates memory?
>
Not all C++ features need to be used in the kernel. In fact, not all C++ 
features need to be used, period. Ever tried to understand code which 
uses overloaded operator,() (the comma operator)?

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:58     ` Alan Cox
@ 2006-04-25  7:20       ` Avi Kivity
  2006-04-25  9:06         ` Matt Keenan
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  7:20 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

Alan Cox wrote:
> On Maw, 2006-04-25 at 00:03 +0300, Avi Kivity wrote:
>   
>> Alan Cox wrote:
>> I think it's easy to show that the equivalent C++ code would be shorter, 
>> faster, and safer.
>>     
>
> Mathematically the answer is "no you couldn't". You might be able to
> argue that a fortran implementation would be faster but not a C++ one.
>   
Maybe not mathematically, but I can try to hand-wave my way through.

By using exceptions, you free the normal return paths from having to 
check for errors. The exception paths can be kept in a dedicated 
section, avoiding cache pollution. The total code (and data) size 
increases, but the non-exception paths size decreases significantly and 
becomes faster.

Using C++ objects instead of C objects allows you to avoid void 
pointers, which are difficult for the compiler to optimize due to aliasing.
> And for strings C++ strings are suprisingly inefficient and need a lot
> of memory allocations, which can fail and are not handled well without C
> ++ exceptions and other joyous language features you don't want in a
> kernel. C with 'safe' string handling is similar - look at glib.
>
> We have to make tradeoffs and the kernel tradeoffs have been to keep C
> type fast string handling but to provide helpers in the hope people will
> actually use them to avoid making mistakes.
>   
You might keep C strings (or something similar) for the vfs paths and 
use C++ strings for non performance critical code.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:18     ` Martin Mares
  2006-04-24 21:36       ` Jeff V. Merkey
  2006-04-24 23:02       ` David Schwartz
@ 2006-04-25  7:33       ` Avi Kivity
  2006-04-25  7:47         ` Nick Piggin
  2006-05-13 16:21         ` Esben Nielsen
  2 siblings, 2 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  7:33 UTC (permalink / raw)
  To: Martin Mares; +Cc: linux-kernel

[original poster de-cc'ed]

Martin Mares wrote:
> Can you name any reasons for why should we support C++ in the kernel?
>   
1. Porting existing modules written in C++ - the trigger for this thread?

2. Shorter, faster, more robust code.
> Why shouldn't we invest the effort to making it possible to write kernel
> modules in Haskell instead?
>   
C++ is a system programming language with good C compatibility. Making 
the kernel compatible with C++ is doable.

Haskell is an excellent language, but it is not a system programming 
language. Kernel programming does not fit well into the functional model.
> The kernel is written in C and its maintainers have so far agreed that
> C is enough and adding any other language brings more pain than gain.
>
> If you think otherwise, feel free to submit some real code which shows
> the advantages of using a different language.
>   
That's certainly doable, however it is quite pointless since we know 
that the code will be rejected regardless of any technical merits it may 
have.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  7:33       ` Avi Kivity
@ 2006-04-25  7:47         ` Nick Piggin
  2006-05-13 16:21         ` Esben Nielsen
  1 sibling, 0 replies; 200+ messages in thread
From: Nick Piggin @ 2006-04-25  7:47 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Martin Mares, linux-kernel

Avi Kivity wrote:
> [original poster de-cc'ed]
> 
> Martin Mares wrote:
> 
>> Can you name any reasons for why should we support C++ in the kernel?
>>   
> 
> 1. Porting existing modules written in C++ - the trigger for this thread?
> 
> 2. Shorter, faster, more robust code.
> 
>> Why shouldn't we invest the effort to making it possible to write kernel
>> modules in Haskell instead?
>>   
> 
> C++ is a system programming language with good C compatibility. Making 
> the kernel compatible with C++ is doable.

You could call it Linux++ and discuss it to your heart's content in l++kml ;)

-- 
SUSE Labs, Novell Inc.
Send instant messages to your online friends http://au.messenger.yahoo.com 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:03   ` Avi Kivity
                       ` (3 preceding siblings ...)
  2006-04-25  4:17     ` Martin J. Bligh
@ 2006-04-25  7:56     ` Jakob Oestergaard
  2006-04-25  9:03     ` Jan Engelhardt
  5 siblings, 0 replies; 200+ messages in thread
From: Jakob Oestergaard @ 2006-04-25  7:56 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Alan Cox, Gary Poppitz, linux-kernel

On Tue, Apr 25, 2006 at 12:03:46AM +0300, Avi Kivity wrote:
> Alan Cox wrote:
> >There are a few anti C++ bigots around too, but the kernel choice of C
> >was based both on rational choices and experimentation early on with the
> >C++ compiler.
> >  
> Times have changed, though. The C++ compiler is much better now, and the 
> recent slew of error handling bugs shows that C is a very unsafe language.
> 
> I think it's easy to show that the equivalent C++ code would be shorter, 
> faster, and safer.

Please read:
 http://unthought.net/c++/c_vs_c++.html

This explains, in simple terms, why you are just as right as you are
wrong.

Snippet:
-------------
Note, that I am not arguing that everything is rewritten in C++. There
are many large projects out there which are written in C - I do not
believe that it is a good idea to just "convert" them to C++. C++ allows
for cleaner solutions than C does, for a great many problems. Doing a
minimal conversion of a solution which is "as clean as it gets" in C, to
C++, would convert "good C" code into "poor C++". That is not a change
to the better!
-------------

And let's forget about this thread then please.

-- 

 / jakob


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 22:16           ` J.A. Magallon
  2006-04-25  0:05             ` Harald Arnesen
  2006-04-25  1:30             ` linux-os (Dick Johnson)
@ 2006-04-25  8:15             ` Xavier Bestel
  2006-04-25  8:42               ` Avi Kivity
  2006-04-25  9:09             ` Nikita Danilov
                               ` (2 subsequent siblings)
  5 siblings, 1 reply; 200+ messages in thread
From: Xavier Bestel @ 2006-04-25  8:15 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Alan Cox, Linux-Kernel,

On Tue, 2006-04-25 at 00:16, J.A. Magallon wrote:

> Tell me what is the difference between:
> 
> 
>     sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
>     if (!sbi)
>         return -ENOMEM;
>     sb->s_fs_info = sbi;
>     memset(sbi, 0, sizeof(*sbi));
>     sbi->s_mount_opt = 0;
>     sbi->s_resuid = EXT3_DEF_RESUID;
>     sbi->s_resgid = EXT3_DEF_RESGID;
> 
> and
> 
>     SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>     {}
> 
>     ...
>     sbi = new SuperBlock;
>     if (!sbi)
>         return -ENOMEM;

In the first case you know that exactely *one* kmalloc(GFP_KERNEL)
occurs. In the second case you have to browse SuperBlock's constructor
to check if it allocates things, needs to run with/without interrupts,
PREEMPT, whatever... (not even talking about exceptions).

	Xav



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  8:15             ` Xavier Bestel
@ 2006-04-25  8:42               ` Avi Kivity
  2006-04-25  8:52                 ` Martin Mares
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  8:42 UTC (permalink / raw)
  To: Xavier Bestel; +Cc: J.A. Magallon, Alan Cox, Linux-Kernel,

Xavier Bestel wrote:
> In the first case you know that exactely *one* kmalloc(GFP_KERNEL)
> occurs. In the second case you have to browse SuperBlock's constructor
> to check if it allocates things, needs to run with/without interrupts,
> PREEMPT, whatever... (not even talking about exceptions).
>   
That seems to be a case against writing functions.

Why is a C function acceptable where a C++ constructor isn't?

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  8:42               ` Avi Kivity
@ 2006-04-25  8:52                 ` Martin Mares
  2006-04-25  9:00                   ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-04-25  8:52 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Xavier Bestel, J.A. Magallon, Alan Cox, Linux-Kernel,

Hello!

> That seems to be a case against writing functions.
> 
> Why is a C function acceptable where a C++ constructor isn't?

Because examining a single constructor is not enough -- you need to
check constructors of all objects contained within the object you
initialize.

Calling a C function is simple and explicit -- a quick glance over
the code is enough to tell what gets called.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Man is the highest animal. Man does the classifying.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 23:02       ` David Schwartz
@ 2006-04-25  8:55         ` Martin Mares
  2006-04-25  8:59           ` Jan Engelhardt
  2006-04-25 14:37           ` David Schwartz
  0 siblings, 2 replies; 200+ messages in thread
From: Martin Mares @ 2006-04-25  8:55 UTC (permalink / raw)
  To: David Schwartz; +Cc: Linux-Kernel@Vger. Kernel. Org

> 	I don't recall anyone asking you to so much as lift a finger. Feel free to
> invest your effort where you feel it will do the most good, and try not to
> criticize others for doing the same with their own resources.

As far as they intend to stay away from the main kernel tree, I don't
critize anybody. But for example renaming otherwise logically named structure
members (`class' etc.) just for C++ compatibility _IS_ wasting time of
other people, who need to remember new names, review the patch and so on.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
If at first you don't succeed, redefine success.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25  5:30       ` Avi Kivity
@ 2006-04-25  8:58         ` Sam Ravnborg
  0 siblings, 0 replies; 200+ messages in thread
From: Sam Ravnborg @ 2006-04-25  8:58 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Martin J. Bligh, Alan Cox, linux-kernel

On Tue, Apr 25, 2006 at 08:30:36AM +0300, Avi Kivity wrote:
> Martin J. Bligh wrote:
> >
> >So ... what exactly are you waiting for? We await the results with
> >baited breath. This slick C++ kernel of which you speak can surely
> >not be far away.
> >
> I'll start on converting 2.6.16 tomorrow, since you're anticipating it 
> with such eagerness.
If you search the archives you can find a simple kbuild patch to
introduce C++ support.
OK, googled a little:
http://www.ussg.iu.edu/hypermail/linux/kernel/0509.2/0549.html

I wrote it for someone that requested it long ago - and never applied it
to vanilla kernel.

They had done the hard stuff themself - adapting the rest of the kernel
to be compileable by a C++ compiler.

	Sam

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  8:55         ` Martin Mares
@ 2006-04-25  8:59           ` Jan Engelhardt
  2006-04-25 14:37           ` David Schwartz
  1 sibling, 0 replies; 200+ messages in thread
From: Jan Engelhardt @ 2006-04-25  8:59 UTC (permalink / raw)
  To: Martin Mares; +Cc: David Schwartz, Linux-Kernel@Vger. Kernel. Org

>> 	I don't recall anyone asking you to so much as lift a finger. Feel free to
>> invest your effort where you feel it will do the most good, and try not to
>> criticize others for doing the same with their own resources.
>
>As far as they intend to stay away from the main kernel tree, I don't
>critize anybody. But for example renaming otherwise logically named structure
>members (`class' etc.) just for C++ compatibility _IS_ wasting time of
>other people, who need to remember new names, review the patch and so on.
>
That said, VMware does use C++ in its kernel modules at one point. So, it 
is possible to some degree with enough effort. Of the
C++ kernel module writer, that is!


Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  8:52                 ` Martin Mares
@ 2006-04-25  9:00                   ` Avi Kivity
  2006-04-25  9:05                     ` Martin Mares
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  9:00 UTC (permalink / raw)
  To: Martin Mares; +Cc: Xavier Bestel, J.A. Magallon, Alan Cox, Linux-Kernel,

Martin Mares wrote:
>   
>> That seems to be a case against writing functions.
>>
>> Why is a C function acceptable where a C++ constructor isn't?
>>     
>
> Because examining a single constructor is not enough -- you need to
> check constructors of all objects contained within the object you
> initialize.
>
> Calling a C function is simple and explicit -- a quick glance over
> the code is enough to tell what gets called.
>
>   
No, you need to check all the functions it calls as well.

But I agree that C is more explicit than C++.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:03   ` Avi Kivity
                       ` (4 preceding siblings ...)
  2006-04-25  7:56     ` Jakob Oestergaard
@ 2006-04-25  9:03     ` Jan Engelhardt
  5 siblings, 0 replies; 200+ messages in thread
From: Jan Engelhardt @ 2006-04-25  9:03 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Alan Cox, Gary Poppitz, linux-kernel

>
> I think it's easy to show that the equivalent C++ code would be shorter,
> faster, and safer.
>
I doubt that. Mixing C and C++ leads to C++ code being slightly bigger than 
intended. In C, you can have

  struct ops *p = void_ptr;

In C++,

  struct ops *p = (struct ops *)void_ptr

or even

  struct ops *p = static_cast<struct ops *>(void_ptr);

And void*s are used a lot.


Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  9:00                   ` Avi Kivity
@ 2006-04-25  9:05                     ` Martin Mares
  2006-04-25  9:13                       ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-04-25  9:05 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Xavier Bestel, J.A. Magallon, Alan Cox, Linux-Kernel,

> >Calling a C function is simple and explicit -- a quick glance over
> >the code is enough to tell what gets called.
> >
> No, you need to check all the functions it calls as well.

Yes, but if it calls none (or calls basic functions I already know),
it's immediately visible without having to circumnavigate the globe
to find declarations of all sub-objects :)

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Homo homini lupus, frater fratri lupior, bohemus bohemo lupissimus.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25  7:20       ` Avi Kivity
@ 2006-04-25  9:06         ` Matt Keenan
  2006-04-25 20:29           ` Bongani Hlope
  0 siblings, 1 reply; 200+ messages in thread
From: Matt Keenan @ 2006-04-25  9:06 UTC (permalink / raw)
  To: Avi Kivity, LKML

Avi Kivity wrote:
> Alan Cox wrote:
>> On Maw, 2006-04-25 at 00:03 +0300, Avi Kivity wrote:
>>  
>>> Alan Cox wrote:
>>> I think it's easy to show that the equivalent C++ code would be 
>>> shorter, faster, and safer.
>>>     
>>
>> Mathematically the answer is "no you couldn't". You might be able to
>> argue that a fortran implementation would be faster but not a C++ one.
>>   
> Maybe not mathematically, but I can try to hand-wave my way through.
>
> By using exceptions, you free the normal return paths from having to 
> check for errors. The exception paths can be kept in a dedicated 
> section, avoiding cache pollution. The total code (and data) size 
> increases, but the non-exception paths size decreases significantly 
> and becomes faster.
>
> Using C++ objects instead of C objects allows you to avoid void 
> pointers, which are difficult for the compiler to optimize due to 
> aliasing.
Exception handling on a kernel with a 4K stack would be very 
interesting, now imagine what would happen if one exception triggered 
another? and possibly another?? And even giving up on the stack issues, 
what about cacheline / performance issues? Moving error handling even 
further from the fast path isn't going to help performance much.. How 
about an exception for every ENOENT? Have you seen how many ENOENT's 
/lib/ld-linux.so.2 generates when a large app starts? Take firefox, load 
it, let it open five tabs, then shut it down. On my system, 1377 
open()'s, 527 of which are ENOENT, 135 of those before the program has 
finished linking. Not exactly the best way to speed the system up. And 
don't say you can use the dentry cache to return an object or NULL, as 
this is just replication of what C does, but with even more syntatic 
goop. C++ is a good tool, for the right job. The kernel is not one of them.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 22:16           ` J.A. Magallon
                               ` (2 preceding siblings ...)
  2006-04-25  8:15             ` Xavier Bestel
@ 2006-04-25  9:09             ` Nikita Danilov
  2006-04-25 20:10               ` J.A. Magallon
  2006-04-25 18:02             ` Geert Uytterhoeven
  2006-04-27  9:09             ` Alexander E. Patrakov
  5 siblings, 1 reply; 200+ messages in thread
From: Nikita Danilov @ 2006-04-25  9:09 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Linux Kernel Mailing List

J.A. Magallon writes:

[...]

 > 
 > Tell me what is the difference between:
 > 
 > 
 >     sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
 >     if (!sbi)
 >         return -ENOMEM;
 >     sb->s_fs_info = sbi;
 >     memset(sbi, 0, sizeof(*sbi));
 >     sbi->s_mount_opt = 0;
 >     sbi->s_resuid = EXT3_DEF_RESUID;
 >     sbi->s_resgid = EXT3_DEF_RESGID;
 > 
 > and
 > 
 >     SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
 >     {}
 > 
 >     ...
 >     sbi = new SuperBlock;
 >     if (!sbi)
 >         return -ENOMEM;
 > 
 > apart that you don't get members initalized twice and get a shorter code :).

The difference is that second fragment doesn't mention GFP_KERNEL, so
it's most likely wrong. Moreover it's shorter only because it places
multiple initializations on the same like, hence, contradicting
CodingStyle.

 > 
 > --
 > J.A. Magallon <jamagallon()able!es>     \               Software is like sex:

Nikita.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  0:46               ` Diego Calleja
@ 2006-04-25  9:12                 ` Harald Arnesen
  0 siblings, 0 replies; 200+ messages in thread
From: Harald Arnesen @ 2006-04-25  9:12 UTC (permalink / raw)
  To: Diego Calleja; +Cc: jamagallon, alan, linux-kernel

Diego Calleja <diegocg@gmail.com> writes:

> El Tue, 25 Apr 2006 02:05:29 +0200,
> Harald Arnesen <harald@skogtun.org> escribió:
>
>> The former is easier to read and understand?
>
> C is not perfect, it could very well get a bit improved so it helps to make 
> the code more readable, etc (and I mean: just improvements, not "lets try to
> turn C into a OO language"). That however requires modifying the current
> C standards, gcc...
>
> But that doesn't justifies adding C++ support to the kernel.

It was the C version I found easier to understand.
-- 
Hilsen Harald.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  9:05                     ` Martin Mares
@ 2006-04-25  9:13                       ` Avi Kivity
  2006-04-25  9:22                         ` Xavier Bestel
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25  9:13 UTC (permalink / raw)
  To: Martin Mares; +Cc: Xavier Bestel, J.A. Magallon, Alan Cox, Linux-Kernel,

Martin Mares wrote:
>>> Calling a C function is simple and explicit -- a quick glance over
>>> the code is enough to tell what gets called.
>>>
>>>       
>> No, you need to check all the functions it calls as well.
>>     
>
> Yes, but if it calls none (or calls basic functions I already know),
> it's immediately visible without having to circumnavigate the globe
> to find declarations of all sub-objects :)
>
>   
Yes, but if the constructor constructs no sub objects (or basic objects 
you already know) then it's immediately visible as well.


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  9:13                       ` Avi Kivity
@ 2006-04-25  9:22                         ` Xavier Bestel
  2006-04-25 20:20                           ` J.A. Magallon
  0 siblings, 1 reply; 200+ messages in thread
From: Xavier Bestel @ 2006-04-25  9:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Martin Mares, J.A. Magallon, Alan Cox, Linux-Kernel,

On Tue, 2006-04-25 at 11:13, Avi Kivity wrote:
> Martin Mares wrote:
> >>> Calling a C function is simple and explicit -- a quick glance over
> >>> the code is enough to tell what gets called.
> >>>
> >>>       
> >> No, you need to check all the functions it calls as well.
> >>     
> >
> > Yes, but if it calls none (or calls basic functions I already know),
> > it's immediately visible without having to circumnavigate the globe
> > to find declarations of all sub-objects :)
> >
> >   
> Yes, but if the constructor constructs no sub objects (or basic objects 
> you already know) then it's immediately visible as well.

Yes, "if". With straight C, it's immediatly obvious the kmalloc() is the
only function with side-effects and special requirements - an
experienced hacker won't even look it up. With C++ those may be hidden
behind each object or object member, that's the philosophy of the
language. 
The problem is that in kernel mode you must know precisely when and how
you allocate memory.

	Xav



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25  7:08       ` Avi Kivity
@ 2006-04-25 10:23         ` James Courtier-Dutton
  2006-04-25 15:59         ` Kyle Moffett
  1 sibling, 0 replies; 200+ messages in thread
From: James Courtier-Dutton @ 2006-04-25 10:23 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Alan Cox, linux-kernel

Avi Kivity wrote:
>>
>>
>> The "advantages" of the former over the latter:
>>
>> (1)  Without exceptions (which are fragile in a kernel), the former 
>> can't return an error instead of initializing the Foo.
> Don't discount exceptions so fast. They're exactly what makes the code 
> clearer and more robust.
>
> A very large proportion of error handling consists of:
> - detect the error
> - undo local changes (freeing memory and unlocking spinlocks)
> - propagate the error
>
> Exceptions make that fully automatic. The kernel uses a mix of gotos 
> and alternate returns which bloat the code and are incredibly error 
> prone. See the recent 2.6.16.x for examples.
C++ exceptions are much more error prone than C. Well not exactly error 
prone, but more non-deterministic.
This is one of the reasons that Software standards allow C++ at lower 
levels, e.g. DAL E, but at higher levels, e.g. DAL B, C++ is not 
allowed, but C is.
So, one can conclude that a C program can be made more reliable than a 
C++ program. One aim of a kernel is reliability.

James

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-25  8:55         ` Martin Mares
  2006-04-25  8:59           ` Jan Engelhardt
@ 2006-04-25 14:37           ` David Schwartz
  2006-04-25 19:50             ` Martin Mares
  1 sibling, 1 reply; 200+ messages in thread
From: David Schwartz @ 2006-04-25 14:37 UTC (permalink / raw)
  To: Linux-Kernel@Vger. Kernel. Org


> > I don't recall anyone asking you to so much as lift a
> > finger. Feel free to
> > invest your effort where you feel it will do the most good, and
> > try not to
> > criticize others for doing the same with their own resources.

> As far as they intend to stay away from the main kernel tree, I don't
> critize anybody. But for example renaming otherwise logically
> named structure
> members (`class' etc.) just for C++ compatibility _IS_ wasting time of
> other people, who need to remember new names, review the patch and so on.

	Hahaha. So now, it's not good enough that they not ask you to do anything,
they have to actively *prevent* you from choosing to waste time on their
changes?

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-24 21:50       ` marty fouts
  2006-04-24 22:09         ` Martin Mares
@ 2006-04-25 15:32         ` Michael Buesch
  1 sibling, 0 replies; 200+ messages in thread
From: Michael Buesch @ 2006-04-25 15:32 UTC (permalink / raw)
  To: marty fouts; +Cc: linux-kernel, Kyle Moffett

[-- Attachment #1: Type: text/plain, Size: 540 bytes --]

On Monday 24 April 2006 23:50, you wrote:
> Oh, and yeah, a = b + c *is* more readable than
> 
> a = malloc(strlen(b) + strlen(c));
> strcpy(a,b);
> strcat(a,c);
> 
> and contains fewer bugs ;)

and a hidden memory allocation.
Which GFP flag would you use for the allocation?
(And how would you actually _pass_ it)
GFP_KERNEL? Good luck, if you see a
a = b + c;
in atomic context.
GFP_ATOMIC? Well, we both don't want that.
Checking is_atomic() and deciding upon that?
I call that overhead... .

-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25  7:08       ` Avi Kivity
  2006-04-25 10:23         ` James Courtier-Dutton
@ 2006-04-25 15:59         ` Kyle Moffett
  2006-04-25 16:46           ` Avi Kivity
  2006-04-25 17:55           ` Geert Uytterhoeven
  1 sibling, 2 replies; 200+ messages in thread
From: Kyle Moffett @ 2006-04-25 15:59 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Alan Cox, linux-kernel

On Apr 25, 2006, at 03:08:02, Avi Kivity wrote:
> Kyle Moffett wrote:
>> The "advantages" of the former over the latter:
>>
>> (1)  Without exceptions (which are fragile in a kernel), the  
>> former can't return an error instead of initializing the Foo.
> Don't discount exceptions so fast. They're exactly what makes the  
> code clearer and more robust.

Except making exceptions work in the kernel is exceptionally  
nontrivial (sorry about the pun).

> A very large proportion of error handling consists of:
> - detect the error
> - undo local changes (freeing memory and unlocking spinlocks)
> - propagate the error/
>
> Exceptions make that fully automatic. The kernel uses a mix of  
> gotos and alternate returns which bloat the code and are incredibly  
> error prone. See the recent 2.6.16.x for examples.

You talk about code bloat here.  Which of the following fits better  
into a 4k stack?  Which of the following shows the flow of code better?

C version:
	int result;
	spin_lock(&lock);
	
	result = do_something();
	if (result)
		goto out;
	
	result = do_something_else();
	if (result)
		goto out;
	
	out:
	spin_unlock(&lock);
	return result;

C++ version:
	int result;
	TakeLock l(&lock);
	
	do_something();
	do_something_else();

First of all, that extra TakeLock object chews up stack, at least 4  
or 8 bytes of it, depending on your word size.  Secondly with  
standard integer error returns you have one or two easily-predictable  
assembly instructions at each step of the way, whereas with  
exceptions you trade the absence of error handling in the rest of the  
code for a lot of extra instructions at the exception throw and catch  
points.  Secondly, while the former is much longer it shows  
_explicitly_ exactly where the flow of code can go.  In an OS kernel,  
that is critical;  your debugability is directly dependent on how  
easy it is to see where the flow of code is going.

>> (2)  You can't control when you initialize the Foo.  For example  
>> in this code, the "Foo item;" declarations seem to be trivially  
>> relocatable, even if they're not.
>>     spin_lock(&foo_lock);
>>     Foo item1;
>>     Foo item2;
>>     spin_unlock(&foo_lock);
>
> They only seem relocatable with your C glasses on. Put on your C++  
> glasses (much thicker), and initialization no longer seems  
> trivially movable.

This is a really _really_ bad idea for a kernel.  Having simple  
declaration statements have big side effects (like the common  
TakeLock object example I gave above) is bound to lead to people  
screwing up and forgetting about the side effects.  In C it's  
impossible to miss the side effects of a statement; function calls  
are obvious, as is global memory modification.

> On the other hand, you can replace the C code
>
> {
>    Foo item1, item2;
>    int r;
>
>    spin_lock(&foo_lock);
>    if ((r = foo_init(&item1)) < 0) {
>        spin_unlock(&foo_lock);
>        return r;
>    }
>    if ((r = foo_init(&item2)) < 0) {
>        foo_destroy(&item1);
>        spin_unlock(&foo_lock);
>        return r;
>    }
>    foo_destroy(&item2);
>    foo_destroy(&item1);
>    spin_unlock(&foo_lock);
>    return 0;
> }
>
> with
>
> {
>    spinlock_t::guard foo_guard(foo_lock);
>    Foo item1;
>    Foo item2;
> }

Let me point out _again_ how unobvious and fragile the flow of code  
there is.  Not to mention the fact that the C++ compiler can easily  
notice that item1 and item2 are never used and optimize them out  
entirely.  You also totally missed the "int flags" argument you're  
supposed to pass to object specifying allocation parameters, not to  
mention the fact that you just allocated 2 objects of unknown size on  
the stack (which is limited to 4k).  AND there's the fact that the  
order of destruction of foo_guard, item1, and item2 is implementation- 
defined and can't easily be relied upon without adding massive  
amounts of excess braces:

{
	spinlock_t::guard foo_guard(&foo_lock);
	{
		Foo item1;
		{
			Foo item2;
		}
	}
}

Also, your spinlock_t::guard chews up stack space that otherwise  
wouldn't be used.  It would be much better to rewrite your above C  
function like this:

{
	struct foo *item1, *item2;
	int result;
	spin_lock(&foo_lock);
	
	item1 = kmalloc(sizeof(*item1), GFP_KERNEL);
	item2 = kmalloc(sizeof(*item2), GFP_KERNEL);
	if (!item1 || !item2)
		goto out;
	
	result = foo_init(item1, GFP_KERNEL);
	if (result)
		goto out;
	
	result = foo_init(item2, GFP_KERNEL);
	if (result)
		goto out;
	
out:
	/* If alloc and init went ok, register them */
	if (item1 && item2 && !result) {
		result = register_foo_pair(item1, item2);
	}
	
	/* If anything failed, free resources */
	if (!item1 || !item2 || result) {
		kfree(item1);
		kfree(item2);
	}
	
	spin_unlock(&foo_lock);
	return result;
}

> 14 lines vs 3, one variable eliminated. How many potential security  
> vulnerabilities? How much time freed to work on the algorithm/data  
> structure, not on error handling?

Yeah, sure, yours is 3 lines when you omit the following:
(1)  Handling allocation flags like GFP_KERNEL
(2)  Not allocating things on the stack
(3)  Proper cleanup ordering
(4)  Reference counting, garbage collection, or another way to  
selectively free the allocated objects based on success or failure of  
other code.

Those are all critical things that we want to force people to think  
about; in many cases the exact ordering of operations _is_ important  
and that needs to be specified _and_ commented on.  How often do you  
think people write comments talking about things that don't even  
appear in the source code?

Also, since when is error handling _not_ a critical part of the  
algorithm?  You can see in my more complicated example that you only  
want to free the items if the registration was unsuccessful.  How do  
you handle that without adding a refcount to everything (bloat) or  
implementing garbage collection (worse bloat).

>> Does that actually make it any easier to understand the code?  How  
>> does it make it more obvious to be able to write a "+" operator  
>> that allocates memory?
>
> Not all C++ features need to be used in the kernel. In fact, not  
> all C++ features need to be used, period. Ever tried to understand  
> code which uses overloaded operator,() (the comma operator)?

The very fact that the language provides such features mean that  
people would try to get code using them into the kernel.  Have you  
ever looked at all the ugly debugging macros that various people  
use?  The C preprocessor provides few features at all, and yet people  
still abuse those, I don't see why C++ would be any different.

Cheers,
Kyle Moffett



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 15:59         ` Kyle Moffett
@ 2006-04-25 16:46           ` Avi Kivity
  2006-04-25 17:10             ` Dmitry Torokhov
                               ` (2 more replies)
  2006-04-25 17:55           ` Geert Uytterhoeven
  1 sibling, 3 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 16:46 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Alan Cox, linux-kernel

Kyle Moffett wrote:
> On Apr 25, 2006, at 03:08:02, Avi Kivity wrote:
>> Kyle Moffett wrote:
>>> The "advantages" of the former over the latter:
>>>
>>> (1)  Without exceptions (which are fragile in a kernel), the former 
>>> can't return an error instead of initializing the Foo.
>> Don't discount exceptions so fast. They're exactly what makes the 
>> code clearer and more robust.
>
> Except making exceptions work in the kernel is exceptionally 
> nontrivial (sorry about the pun).
My experience with exceptions in kernel-like code (a distributed 
filesystem) was excellent.
>
>> A very large proportion of error handling consists of:
>> - detect the error
>> - undo local changes (freeing memory and unlocking spinlocks)
>> - propagate the error/
>>
>> Exceptions make that fully automatic. The kernel uses a mix of gotos 
>> and alternate returns which bloat the code and are incredibly error 
>> prone. See the recent 2.6.16.x for examples.
>
> You talk about code bloat here.  Which of the following fits better 
> into a 4k stack?  
The C++ code. See below.
> Which of the following shows the flow of code better?
Once you accept the idea that an exception can occur (almost) anywhere, 
the C++ code shows you what the code does in the normal case without 
obfuscating it with error handling. Pretend that after every semicolon 
there is a comment of the form:

    /* possible exceptional return */

once you think like that, you can see what the code actually does rather 
than how it handles errors. A 15-line function can do something 
meaningful, not just call two functions.
>
> C version:
>     int result;
>     spin_lock(&lock);
>     
>     result = do_something();
>     if (result)
>         goto out;
>     
>     result = do_something_else();
>     if (result)
>         goto out;
>     
>     out:
>     spin_unlock(&lock);
>     return result;
>
> C++ version:
>     int result;
not needed unless you actually return something.
>     TakeLock l(&lock);
>     
>     do_something();
>     do_something_else();
>
> First of all, that extra TakeLock object chews up stack, at least 4 or 
> 8 bytes of it, depending on your word size.
No, it's optimized out. gcc notices that &lock doesn't change and that 
'l' never escapes the function.
>   Secondly with standard integer error returns you have one or two 
> easily-predictable assembly instructions at each step of the way, 
> whereas with exceptions you trade the absence of error handling in the 
> rest of the code for a lot of extra instructions at the exception 
> throw and catch points.
The extra code is out of line (not even an if (unlikely())). So yes, 
total code grows, but the exceptional paths can be in a .text.exception 
section and not consume cache or TLB space.
>   Secondly, while the former is much longer it shows _explicitly_ 
> exactly where the flow of code can go.  In an OS kernel, that is 
> critical;  your debugability is directly dependent on how easy it is 
> to see where the flow of code is going.
>
I can only say that I had very positive experience with code that used 
exceptions. Having less code to view actually improves visibility.
>>> (2)  You can't control when you initialize the Foo.  For example in 
>>> this code, the "Foo item;" declarations seem to be trivially 
>>> relocatable, even if they're not.
>>>     spin_lock(&foo_lock);
>>>     Foo item1;
>>>     Foo item2;
>>>     spin_unlock(&foo_lock);
>>
>> They only seem relocatable with your C glasses on. Put on your C++ 
>> glasses (much thicker), and initialization no longer seems trivially 
>> movable.
>
> This is a really _really_ bad idea for a kernel.  Having simple 
> declaration statements have big side effects (like the common TakeLock 
> object example I gave above) is bound to lead to people screwing up 
> and forgetting about the side effects.  In C it's impossible to miss 
> the side effects of a statement; function calls are obvious, as is 
> global memory modification.
>
In C++ you just have to treat declarations as executable statements. 
Just as you can't compile the code with a C compiler, you can't read it 
with a C mindset. Once you get used to it, it isn't surprising at all.
>> On the other hand, you can replace the C code
>>
>> {
>>    Foo item1, item2;
>>    int r;
>>
>>    spin_lock(&foo_lock);
>>    if ((r = foo_init(&item1)) < 0) {
>>        spin_unlock(&foo_lock);
>>        return r;
>>    }
>>    if ((r = foo_init(&item2)) < 0) {
>>        foo_destroy(&item1);
>>        spin_unlock(&foo_lock);
>>        return r;
>>    }
>>    foo_destroy(&item2);
>>    foo_destroy(&item1);
>>    spin_unlock(&foo_lock);
>>    return 0;
>> }
>>
>> with
>>
>> {
>>    spinlock_t::guard foo_guard(foo_lock);
>>    Foo item1;
>>    Foo item2;
>> }
>
> Let me point out _again_ how unobvious and fragile the flow of code 
> there is.  Not to mention the fact that the C++ compiler can easily 
> notice that item1 and item2 are never used and optimize them out entirely.
Excellent! If there are no side effects, I want it out. If there are 
side effects, it won't optimize them out.
>   You also totally missed the "int flags" argument you're supposed to 
> pass to object specifying allocation parameters,
There is no allocation here (both the C and the C++ code allocate on the 
stack.

Should you want to allocate from the heap, try this:

{
    spinlock_t::guard g(some_lock);
    auto_ptr<Foo> item(new (gfp_mask) Foo);   /* or pass a kmem_cache_t */
    item->do_something();
    item->do_something_else();
    return item.release();
}
 
contrast with

{
    Foo *item = 0;
    int r;

    spin_lock(&some_lock);
    item = kmalloc(sizeof(Foo), gfp_flags);
    if (!item) {
         item = PTR_ERR(ENOMEM);  
         goto out;
    }
    if ((r = foo_do_something(item))) {
        foo_destroy(item);
        kfree(item);
        item = PTR_ERR(-r);
        goto out;
    }
    if ((r = foo_do_something_else(item))) {
        foo_destroy(item);
        kfree(item);
        item = PTR_ERR(-r);
    }
out:
    spin_unlock(&some_lock);
    return item;
}

(oops, you wrote another version further on...)
> not to mention the fact that you just allocated 2 objects of unknown 
> size on the stack (which is limited to 4k).
So did the C code. I was just side-by-side comparisons of *equivalent* code.
>   AND there's the fact that the order of destruction of foo_guard, 
> item1, and item2 is implementation-defined and can't easily be relied 
> upon without adding massive amounts of excess braces:
It is well defined. guard ctor, item1 ctor, item2 ctor, item2 dtor, 
item1 dtor, guard dtor.

It is also well defined that if a constructor is executed for an 
automatic variable, so will its destructor. That makes the "guard" work 
so well with exceptions.
>
> {
>     spinlock_t::guard foo_guard(&foo_lock);
>     {
>         Foo item1;
>         {
>             Foo item2;
>         }
>     }
> }
>
Absolutely unneeded braces there.
> Also, your spinlock_t::guard chews up stack space that otherwise 
> wouldn't be used.  It would be much better to rewrite your above C 
> function like this:
>
> {
>     struct foo *item1, *item2;
>     int result;
>     spin_lock(&foo_lock);
>     
>     item1 = kmalloc(sizeof(*item1), GFP_KERNEL);
>     item2 = kmalloc(sizeof(*item2), GFP_KERNEL);
>     if (!item1 || !item2)
>         goto out;
>     
>     result = foo_init(item1, GFP_KERNEL);
>     if (result)
>         goto out;
>     
>     result = foo_init(item2, GFP_KERNEL);
>     if (result)
>         goto out;
>     
> out:
>     /* If alloc and init went ok, register them */
>     if (item1 && item2 && !result) {
>         result = register_foo_pair(item1, item2);
>     }
>     
>     /* If anything failed, free resources */
>     if (!item1 || !item2 || result) {
>         kfree(item1);
>         kfree(item2);
>     }
>     
>     spin_unlock(&foo_lock);
>     return result;
> }
>
>> 14 lines vs 3, one variable eliminated. How many potential security 
>> vulnerabilities? How much time freed to work on the algorithm/data 
>> structure, not on error handling?
>
> Yeah, sure, yours is 3 lines when you omit the following:
> (1)  Handling allocation flags like GFP_KERNEL
done
> (2)  Not allocating things on the stack
done
> (3)  Proper cleanup ordering
done, without lifting a finger
> (4)  Reference counting, garbage collection, or another way to 
> selectively free the allocated objects based on success or failure of 
> other code.
Reference counting is ridiculously to do in C++. I'll spare you the details.
>
> Those are all critical things that we want to force people to think 
> about; in many cases the exact ordering of operations _is_ important 
> and that needs to be specified _and_ commented on.  How often do you 
> think people write comments talking about things that don't even 
> appear in the source code?
C++ preserves the order (unless it can prove the order doesn't matter, 
same as C)
>
> Also, since when is error handling _not_ a critical part of the 
> algorithm?  You can see in my more complicated example that you only 
> want to free the items if the registration was unsuccessful.  How do 
> you handle that without adding a refcount to everything (bloat) or 
> implementing garbage collection (worse bloat).
Use auto_ptr<>.

Yes, error handling is critical. That's why I want language help. Just 
like I don't want to:
- calculate the carry for 64 bit addition on a 32 bit machine
- calculate structure offsets for structs (even though struct layout is 
important)

I faced exactly these problems (fibre channel and ethernet cables pulled 
out during I/O) and C++ made error handling easier, not more difficult.

>
>>> Does that actually make it any easier to understand the code?  How 
>>> does it make it more obvious to be able to write a "+" operator that 
>>> allocates memory?
>>
>> Not all C++ features need to be used in the kernel. In fact, not all 
>> C++ features need to be used, period. Ever tried to understand code 
>> which uses overloaded operator,() (the comma operator)?
>
> The very fact that the language provides such features mean that 
> people would try to get code using them into the kernel.  Have you 
> ever looked at all the ugly debugging macros that various people use?  
> The C preprocessor provides few features at all, and yet people still 
> abuse those, I don't see why C++ would be any different.
Probably not. I agree C++ is much more abusable.

BTW, under C++ preprocessor abuse drops significantly as it can be 
replaced by safer and cleaner constructs.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 16:46           ` Avi Kivity
@ 2006-04-25 17:10             ` Dmitry Torokhov
  2006-04-25 17:19               ` Avi Kivity
  2006-04-25 19:22             ` Kyle Moffett
  2006-04-25 20:11             ` Bongani Hlope
  2 siblings, 1 reply; 200+ messages in thread
From: Dmitry Torokhov @ 2006-04-25 17:10 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Alan Cox, linux-kernel

On 4/25/06, Avi Kivity <avi@argo.co.il> wrote:
> Kyle Moffett wrote:
> > On Apr 25, 2006, at 03:08:02, Avi Kivity wrote:
> >> Kyle Moffett wrote:
> >>> The "advantages" of the former over the latter:
> >>>
> >>> (1)  Without exceptions (which are fragile in a kernel), the former
> >>> can't return an error instead of initializing the Foo.
> >> Don't discount exceptions so fast. They're exactly what makes the
> >> code clearer and more robust.
> >
> > Except making exceptions work in the kernel is exceptionally
> > nontrivial (sorry about the pun).
> My experience with exceptions in kernel-like code (a distributed
> filesystem) was excellent.
> >
> >> A very large proportion of error handling consists of:
> >> - detect the error
> >> - undo local changes (freeing memory and unlocking spinlocks)
> >> - propagate the error/
> >>
> >> Exceptions make that fully automatic. The kernel uses a mix of gotos
> >> and alternate returns which bloat the code and are incredibly error
> >> prone. See the recent 2.6.16.x for examples.
> >
> > You talk about code bloat here.  Which of the following fits better
> > into a 4k stack?
> The C++ code. See below.
> > Which of the following shows the flow of code better?
> Once you accept the idea that an exception can occur (almost) anywhere,
> the C++ code shows you what the code does in the normal case without
> obfuscating it with error handling. Pretend that after every semicolon
> there is a comment of the form:
>
>    /* possible exceptional return */
>
> once you think like that, you can see what the code actually does rather
> than how it handles errors. A 15-line function can do something
> meaningful, not just call two functions.
> >
> > C version:
> >     int result;
> >     spin_lock(&lock);
> >
> >     result = do_something();
> >     if (result)
> >         goto out;
> >
> >     result = do_something_else();
> >     if (result)
> >         goto out;
> >
> >     out:
> >     spin_unlock(&lock);
> >     return result;
> >
> > C++ version:
> >     int result;
> not needed unless you actually return something.
> >     TakeLock l(&lock);
> >
> >     do_something();
> >     do_something_else();
> >
> > First of all, that extra TakeLock object chews up stack, at least 4 or
> > 8 bytes of it, depending on your word size.
> No, it's optimized out. gcc notices that &lock doesn't change and that
> 'l' never escapes the function.

"l" that propects critical section gets thrown away??? What is the
name of the filesystem you ported? I mean, I need to know so I don't
use it by accident.

--
Dmitry

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:10             ` Dmitry Torokhov
@ 2006-04-25 17:19               ` Avi Kivity
  2006-04-25 17:28                 ` Dmitry Torokhov
  2006-04-25 17:54                 ` linux-os (Dick Johnson)
  0 siblings, 2 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 17:19 UTC (permalink / raw)
  To: dtor_core; +Cc: Kyle Moffett, Alan Cox, linux-kernel

Dmitry Torokhov wrote:
>>>     TakeLock l(&lock);
>>>
>>>     do_something();
>>>     do_something_else();
>>>
>>> First of all, that extra TakeLock object chews up stack, at least 4 or
>>> 8 bytes of it, depending on your word size.
>>>       
>> No, it's optimized out. gcc notices that &lock doesn't change and that
>> 'l' never escapes the function.
>>     
>
> "l" that propects critical section gets thrown away??? 
Calm down, the storage for 'l' is thrown away, but its effects remain.
> What is the
> name of the filesystem you ported? I mean, I need to know so I don't
> use it by accident.
>   
It's very expensive, you can't use it by accident.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:19               ` Avi Kivity
@ 2006-04-25 17:28                 ` Dmitry Torokhov
  2006-04-25 17:53                   ` Avi Kivity
  2006-04-25 17:54                 ` linux-os (Dick Johnson)
  1 sibling, 1 reply; 200+ messages in thread
From: Dmitry Torokhov @ 2006-04-25 17:28 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Alan Cox, linux-kernel

On 4/25/06, Avi Kivity <avi@argo.co.il> wrote:
> Dmitry Torokhov wrote:
> >>>     TakeLock l(&lock);
> >>>
> >>>     do_something();
> >>>     do_something_else();
> >>>
> >>> First of all, that extra TakeLock object chews up stack, at least 4 or
> >>> 8 bytes of it, depending on your word size.
> >>>
> >> No, it's optimized out. gcc notices that &lock doesn't change and that
> >> 'l' never escapes the function.
> >>
> >
> > "l" that propects critical section gets thrown away???
> Calm down, the storage for 'l' is thrown away, but its effects remain.

Would you mind explaining implemenation details a little bit?

--
Dmitry

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:28                 ` Dmitry Torokhov
@ 2006-04-25 17:53                   ` Avi Kivity
  2006-04-25 18:04                     ` Dmitry Torokhov
                                       ` (2 more replies)
  0 siblings, 3 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 17:53 UTC (permalink / raw)
  To: dtor_core; +Cc: Kyle Moffett, Alan Cox, linux-kernel

Dmitry Torokhov wrote:
>>>>>           
>>>> No, it's optimized out. gcc notices that &lock doesn't change and that
>>>> 'l' never escapes the function.
>>>>
>>>>         
>>> "l" that propects critical section gets thrown away???
>>>       
>> Calm down, the storage for 'l' is thrown away, but its effects remain.
>>     
>
> Would you mind explaining implemenation details a little bit?
>   
(I don't know how familiar you are with C++ so I'm explaining it from 
the basics, apologies if I'm repeating things you know)

Very often one needs to acquire a resource, do something with it, and 
then free the resource. Here, "resource" can mean a file descriptor, a 
reference into a reference counted object, or, in our case, a spinlock. 
And we want "free" to mean "free no matter what", e.g. on a normal path 
or an exception path.

In C++, you code it as a guard object:

struct spinlock_guard {
    spinlock_guard(spinlock_t *lock) { sl = lock; spin_lock(sl); }
    ~spinlock_guard() { spin_unlock(sl); }

    spinlock_t *sl;
};

(this would be coded differently, trying to keep it C-like)

To use it, create a spinlock_guard object that goes into scope before 
you use the data you want to protect:

spinlock_t some_lock.;

void f()
{
    blah();
     spinlock_guard guard(&some_lock);
     __f(); /* do nonatomic stuff */
     if (__g())
         return;
     __h()
}

C++ treats this as if you've written:

spinlock_t some_lock;

void f()
{
    spinlock_guard guard;

    blah();
    guard.sl = &some_lock;
    spin_lock(guard.sl);
    __f();
    if (__g())
        goto out;
    __h();
out:
    spin_unlock(guard.sl);
}

Additionally, C++ guarantees that if an exception is thrown after 
spin_lock() is called, then the spin_unlock() will also be called. 
That's an interesting mechanism by itself.

Now, the optimizer sees that guard.sl is a constant expression 
(&some_lock), and that guard.sl's address is not passed to any function, 
so it eliminates the variable entirely, leaving us with


spinlock_t some_lock;

void f()
{
    blah();
    spin_lock(&some_lock);
    __f();
    if (__g())
        goto out;
    __h();
out:
    spin_unlock(&some_lock);
}

(the original C++ compiler actually worked by writing out the C code and 
letting the C compiler compile it; nowadays both compilers use the same 
intermediate representation, optimizer, and code generator).

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:19               ` Avi Kivity
  2006-04-25 17:28                 ` Dmitry Torokhov
@ 2006-04-25 17:54                 ` linux-os (Dick Johnson)
  2006-04-26  8:30                   ` Jan Engelhardt
  1 sibling, 1 reply; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-25 17:54 UTC (permalink / raw)
  To: Avi Kivity; +Cc: dtor_core, Kyle Moffett, Alan Cox, linux-kernel


On Tue, 25 Apr 2006, Avi Kivity wrote:

> Dmitry Torokhov wrote:
>>>>     TakeLock l(&lock);
>>>>
>>>>     do_something();
>>>>     do_something_else();
>>>>
>>>> First of all, that extra TakeLock object chews up stack, at least 4 or
>>>> 8 bytes of it, depending on your word size.
>>>>
>>> No, it's optimized out. gcc notices that &lock doesn't change and that
>>> 'l' never escapes the function.
>>>
>>
>> "l" that propects critical section gets thrown away???
> Calm down, the storage for 'l' is thrown away, but its effects remain.
>> What is the
>> name of the filesystem you ported? I mean, I need to know so I don't
>> use it by accident.
>>
> It's very expensive, you can't use it by accident.

Class Kernel
{
public:
     virtual void starter(Scheduler *current) = 0x00;
};

Okay, I just started your new C++ kernel! Please send email when it
is done. I will help test it.

> --
> Do not meddle in the internals of kernels, for they are subtle and quick to panic.
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
Warning : 98.36% of all statistics are fiction, book release in April.
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 15:59         ` Kyle Moffett
  2006-04-25 16:46           ` Avi Kivity
@ 2006-04-25 17:55           ` Geert Uytterhoeven
  1 sibling, 0 replies; 200+ messages in thread
From: Geert Uytterhoeven @ 2006-04-25 17:55 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Avi Kivity, Alan Cox, Linux Kernel Development

On Tue, 25 Apr 2006, Kyle Moffett wrote:
> On Apr 25, 2006, at 03:08:02, Avi Kivity wrote:
> > {
> >    spinlock_t::guard foo_guard(foo_lock);
> >    Foo item1;
> >    Foo item2;
> > }
> 
> Let me point out _again_ how unobvious and fragile the flow of code there is.
> Not to mention the fact that the C++ compiler can easily notice that item1 and
> item2 are never used and optimize them out entirely.  You also totally missed

Only if the constructor and destructor of Foo is inline. Else there may be side
effects.

This is commonly used for function scope debugging, and I never saw the
compiler optimize away any of these debug objects, even if they look unused to
the casual reader.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 22:16           ` J.A. Magallon
                               ` (3 preceding siblings ...)
  2006-04-25  9:09             ` Nikita Danilov
@ 2006-04-25 18:02             ` Geert Uytterhoeven
  2006-04-27  9:09             ` Alexander E. Patrakov
  5 siblings, 0 replies; 200+ messages in thread
From: Geert Uytterhoeven @ 2006-04-25 18:02 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Alan Cox, Linux-Kernel, 

On Tue, 25 Apr 2006, J.A. Magallon wrote:
> On Mon, 24 Apr 2006 22:52:12 +0100, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> > This is one area of concern. Just as big a problem for the OS case is
> > that the hidden constructors/destructors may fail.
> 
> Tell me what is the difference between:
> 
> 
>     sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
>     if (!sbi)
>         return -ENOMEM;
>     sb->s_fs_info = sbi;
>     memset(sbi, 0, sizeof(*sbi));
>     sbi->s_mount_opt = 0;
>     sbi->s_resuid = EXT3_DEF_RESUID;
>     sbi->s_resgid = EXT3_DEF_RESGID;
> 
> and
> 
>     SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>     {}
> 
>     ...
>     sbi = new SuperBlock;

You forgot the `nothrow'.

>     if (!sbi)
>         return -ENOMEM;
> 
> apart that you don't get members initalized twice and get a shorter code :).

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:53                   ` Avi Kivity
@ 2006-04-25 18:04                     ` Dmitry Torokhov
  2006-04-25 18:08                     ` Valdis.Kletnieks
  2006-04-27 15:10                     ` Denis Vlasenko
  2 siblings, 0 replies; 200+ messages in thread
From: Dmitry Torokhov @ 2006-04-25 18:04 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Alan Cox, linux-kernel

On 4/25/06, Avi Kivity <avi@argo.co.il> wrote:
> Dmitry Torokhov wrote:
> >>>>>
> >>>> No, it's optimized out. gcc notices that &lock doesn't change and that
> >>>> 'l' never escapes the function.
> >>>>
> >>>>
> >>> "l" that propects critical section gets thrown away???
> >>>
> >> Calm down, the storage for 'l' is thrown away, but its effects remain.
> >>
> >
> > Would you mind explaining implemenation details a little bit?
> >
> (I don't know how familiar you are with C++ so I'm explaining it from
> the basics, apologies if I'm repeating things you know)
>
> Very often one needs to acquire a resource, do something with it, and
> then free the resource. Here, "resource" can mean a file descriptor, a
> reference into a reference counted object, or, in our case, a spinlock.
> And we want "free" to mean "free no matter what", e.g. on a normal path
> or an exception path.
>
> In C++, you code it as a guard object:
>
> struct spinlock_guard {
>    spinlock_guard(spinlock_t *lock) { sl = lock; spin_lock(sl); }
>    ~spinlock_guard() { spin_unlock(sl); }
>
>    spinlock_t *sl;
> };
>

Oh, I remember now - lock is external wrt the code block it protects
so you just ensure destructor is called at the exit w/o allocating any
actual storage.
Thanks.

--
Dmitry

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:53                   ` Avi Kivity
  2006-04-25 18:04                     ` Dmitry Torokhov
@ 2006-04-25 18:08                     ` Valdis.Kletnieks
  2006-04-25 18:26                       ` Avi Kivity
  2006-04-27 15:10                     ` Denis Vlasenko
  2 siblings, 1 reply; 200+ messages in thread
From: Valdis.Kletnieks @ 2006-04-25 18:08 UTC (permalink / raw)
  To: Avi Kivity; +Cc: dtor_core, Kyle Moffett, Alan Cox, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

On Tue, 25 Apr 2006 20:53:01 +0300, Avi Kivity said:

> Additionally, C++ guarantees that if an exception is thrown after 
> spin_lock() is called, then the spin_unlock() will also be called. 
> That's an interesting mechanism by itself.

Gaak.  So let me get this straight - We lock something, then we hit
an exception because something corrupted the lock.  Then we *unlock* it
so more code can trip over it.

Sometimes the correct semantic is to *leave it locked*.

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 18:08                     ` Valdis.Kletnieks
@ 2006-04-25 18:26                       ` Avi Kivity
  2006-04-25 18:38                         ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 18:26 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: dtor_core, Kyle Moffett, Alan Cox, linux-kernel

Valdis.Kletnieks@vt.edu wrote:
>
> On Tue, 25 Apr 2006 20:53:01 +0300, Avi Kivity said:
>
> > Additionally, C++ guarantees that if an exception is thrown after
> > spin_lock() is called, then the spin_unlock() will also be called.
> > That's an interesting mechanism by itself.
>
> Gaak.  So let me get this straight - We lock something, then we hit
> an exception because something corrupted the lock.  Then we *unlock* it
> so more code can trip over it.
>
> Sometimes the correct semantic is to *leave it locked*.
>
C++ doesn't force *any* semantic on you. It gives you tools to implement 
the semantic you want. If you want the lock to remain unlocked, that is 
of course doable.

Most often (almost always), the cause of the exception is not random 
corruption, but an error (I/O error, out of memory, etc.) and you want 
to unlock the lock. C++ helps you get it right without writing tons of 
boilerplate code:

[avi@cleopatra linux]$ grep -r out.*: . | wc -l
10446

How many times you want it unlocked but it's left locked because of an 
obscure error path? When does 2.6.16.14 come out?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 18:26                       ` Avi Kivity
@ 2006-04-25 18:38                         ` Avi Kivity
  2006-04-25 18:52                           ` Michael Poole
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 18:38 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: dtor_core, Kyle Moffett, Alan Cox, linux-kernel

Avi Kivity wrote:
>
> [avi@cleopatra linux]$ grep -r out.*: . | wc -l
> 10446
>
Not to mention:

[avi@cleopatra linux]$ grep -rw goto . | wc -l
37448

How many of these leave something out? how much time is spent 
deciphering the code when something goes wrong, or is even suspected?


-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 18:38                         ` Avi Kivity
@ 2006-04-25 18:52                           ` Michael Poole
  2006-04-25 19:13                             ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Michael Poole @ 2006-04-25 18:52 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Valdis.Kletnieks, dtor_core, Kyle Moffett, Alan Cox, linux-kernel

Avi Kivity writes:

> Avi Kivity wrote:
> >
> > [avi@cleopatra linux]$ grep -r out.*: . | wc -l
> > 10446
> >
> Not to mention:
> 
> [avi@cleopatra linux]$ grep -rw goto . | wc -l
> 37448
> 
> How many of these leave something out? how much time is spent
> deciphering the code when something goes wrong, or is even suspected?

Probably fewer cases and less time than you suspect, respectively.
Just as C++ gives you tools, C does too, but far more important than
language tools is the discipline used when writing code: discipline to
think through the code, to structure it rationally, and to reuse the
rational structures that others have devised in the past.  C++ gives
you well-tested helper classes to manage object locking.  Linux gives
you its own well-tested examples of known and tried design patterns.

Michael Poole

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 18:52                           ` Michael Poole
@ 2006-04-25 19:13                             ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 19:13 UTC (permalink / raw)
  To: Michael Poole
  Cc: Valdis.Kletnieks, dtor_core, Kyle Moffett, Alan Cox, linux-kernel

Michael Poole wrote:
>> How many of these leave something out? how much time is spent
>> deciphering the code when something goes wrong, or is even suspected?
>>     
>
> Probably fewer cases and less time than you suspect, respectively.
> Just as C++ gives you tools, C does too, but far more important than
> language tools is the discipline used when writing code: discipline to
> think through the code, to structure it rationally, and to reuse the
> rational structures that others have devised in the past.  C++ gives
> you well-tested helper classes to manage object locking.  Linux gives
> you its own well-tested examples of known and tried design patterns.
>   
I agree. It certainly helps when you first write the code. But it's 
still difficult to read and modify the code. And I'd prefer to see the 
effort involved in coding to these patterns and in enforcing them used 
to other purposes.

I also suspect drivers are written with less rigor.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 16:46           ` Avi Kivity
  2006-04-25 17:10             ` Dmitry Torokhov
@ 2006-04-25 19:22             ` Kyle Moffett
  2006-04-25 19:54               ` Michael Buesch
  2006-04-25 20:24               ` Avi Kivity
  2006-04-25 20:11             ` Bongani Hlope
  2 siblings, 2 replies; 200+ messages in thread
From: Kyle Moffett @ 2006-04-25 19:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Alan Cox, linux-kernel

On Apr 25, 2006, at 12:46:02, Avi Kivity wrote:
> Kyle Moffett wrote:
>> Except making exceptions work in the kernel is exceptionally  
>> nontrivial (sorry about the pun).
>
> My experience with exceptions in kernel-like code (a distributed  
> filesystem) was excellent.

Well from all of the discussions about it that occurred on this list,  
the biggest problem with exceptions in the kernel was the overhead to  
keep track of the exception state and the try/catch stack.  The other  
problem was handling exceptions in atomic contexts, in the guts of  
the scheduler, and in a host of other hot-paths.

>> Which of the following shows the flow of code better?
>
> Once you accept the idea that an exception can occur (almost) anywhere

Except they can't.  Lots and lots of bits of kernel code explicitly  
depend on the fact that certain operations _cannot_ fail, and they  
make that obvious through the fact that those functions don't have  
any way of returning error conditions.

> the C++ code shows you what the code does in the normal case  
> without obfuscating it with error handling. Pretend that after  
> every semicolon there is a comment of the form:
>    /* possible exceptional return */

As I pointed out before and seem doomed to point out again, this is  
an _implicit_ piece of code, and in kernels implicit code is very  
very bad.  Because of the varying contexts and close hardware  
dependence, you want to explicitly state everything that happens.

>> First of all, that extra TakeLock object chews up stack, at least  
>> 4 or 8 bytes of it, depending on your word size.
>
> No, it's optimized out. gcc notices that &lock doesn't change and  
> that 'l' never escapes the function.

GCC does not notice that when you use out-of-line functions.  Let me  
remind you that many of the kernel's spinlocks and other functions  
are out-of-line, inlining them has significant performance penalties.

>> Secondly with standard integer error returns you have one or two  
>> easily-predictable assembly instructions at each step of the way,  
>> whereas with exceptions you trade the absence of error handling in  
>> the rest of the code for a lot of extra instructions at the  
>> exception throw and catch points.
>
> The extra code is out of line (not even an if (unlikely())). So  
> yes, total code grows, but the exceptional paths can be in  
> a .text.exception section and not consume cache or TLB space.

Total bull.  Let me give you an example.  The following C++ code:
{
	Foo my_foo;
	function_that_throws_exception();
}

Is turned by the compiler into a slight variant on this C code:
{
	Foo my_foo = Foo();
	jmp_buf exception;
	if (setjmp(exception))
		goto out;
	
	function_that_throws_exception();
	
out:
	~Foo(&my_foo);
}

There is nothing about the above that the compiler can trivially "out- 
of-line", not to mention the fact that you just royally screwed the  
CPUs chances of getting branch prediction right.  There's the fact  
that setjmp and longjmp are kind of hard in kernelspace.  Finally,  
the stack usage is significantly increased, I think even in  
userspace, jmp_buf occupies 8 longs (32 bytes) just for critical  
registers and instruction pointer of the exception handler.  Also,  
the simplest case of throwing an exception has turned from the three  
instructions "cmp bnz ret" (compare result or pointer, branch to  
exception code, return) to this mess:
{
	longjmp((int)pointer);
}

The longjmp function is simple, but not _that_ simple, and it still  
breaks branch prediction in a bad way.

>> This is a really _really_ bad idea for a kernel.  Having simple  
>> declaration statements have big side effects (like the common  
>> TakeLock object example I gave above) is bound to lead to people  
>> screwing up and forgetting about the side effects.  In C it's  
>> impossible to miss the side effects of a statement; function calls  
>> are obvious, as is global memory modification.
>
> In C++ you just have to treat declarations as executable  
> statements. Just as you can't compile the code with a C compiler,  
> you can't read it with a C mindset. Once you get used to it, it  
> isn't surprising at all.

That's all well and good, until you assume that "some_type foo = 3;"  
is just declaring an integer through a typedef instead of declaring  
an object with side effects.  The thing about the linux kernel is  
that basically _nobody_ understands all of it, and as a result each  
and every bit of code must stand on its own and be fairly obvious as  
to side effects and such.  In C++, most of the language features are  
designed to _hide_ those side effects and as a result it's a terrible  
fit for the kernel.

>> Let me point out _again_ how unobvious and fragile the flow of  
>> code there is.  Not to mention the fact that the C++ compiler can  
>> easily notice that item1 and item2 are never used and optimize  
>> them out entirely.
>
> Excellent! If there are no side effects, I want it out. If there  
> are side effects, it won't optimize them out.

How can it tell?  You aren't writing all your member functions  
inline, are you?

>>   You also totally missed the "int flags" argument you're supposed  
>> to pass to object specifying allocation parameters,
>
> There is no allocation here (both the C and the C++ code allocate  
> on the stack.

Let's look in the kernel.  How often do you find non-trivial  
constructor functions that _don't_ allocate memory, hm?

> Should you want to allocate from the heap, try this:
>
> {
>    spinlock_t::guard g(some_lock);
>    auto_ptr<Foo> item(new (gfp_mask) Foo);   /* or pass a  
> kmem_cache_t */
>    item->do_something();
>    item->do_something_else();
>    return item.release();
> }

I think this code speaks for itself about its lack of readability.

>    if ((r = foo_do_something(item))) {

Your kernel-idiomatic C is terrible.  Please don't go around writing  
much kernel code in this style, that's disgusting.  Your multiply- 
duplicated return statements were also bad form, see my example for a  
much clearer way of doing it.

>> Yeah, sure, yours is 3 lines when you omit the following:
>> (1)  Handling allocation flags like GFP_KERNEL
> done

And unreadable afterwards

>> (4)  Reference counting, garbage collection, or another way to  
>> selectively free the allocated objects based on success or failure  
>> of other code.
> Reference counting is ridiculously to do in C++. I'll spare you the  
> details.

I'll assume you mean "ridiculously easy" there.  The problem is that  
with the exception handling system you add refcounts to a lot of  
objects that don't need them.  Here's an example that doesn't need a  
refcount.  I'm registering the "item" with a subsystem, and if that  
fails the object is immediately freed.

{
	int result;
	struct foo *item = kmalloc(sizeof(*item), GFP_KERNEL);
	if (unlikely(!item))
		return ERR_PTR(-ENOMEM);
	
	spin_lock(&item_lock);
	
	result = item_init(item, GFP_KERNEL);
	if (unlikely(result))
		goto free;
	
	result = item_register(subsystem, item);
	if (unlikely(result))
		goto destroy;
	
out:
	spin_unlock(&item_lock);
	return result;

	/* Error handling */
destroy:
	item_destroy(item);
free:
	kfree(item);
	goto out;
}

Please note that the assembly into which this optimizes is quite  
efficient, the compiler can trivially order the fast-path and place  
all of the exception code after the function or could theoretically  
even put it in a different section.  The side-effects are quite  
obvious, and it's also simple to identify exactly how many  
instructions this function costs; there's a memory allocation, a  
lock, and two function calls.  Interspersed in there are exactly 3  
conditional jumps to exception-handling code.  Direct stack usage for  
this function is around 8 or 12 bytes, depending on word size.

The biggest advantage to this method is that we can tell C exactly  
what exceptions we expect from the various functions.  Not only that,  
but we already know what type they are, how likely they are to occur,  
and exactly how to handle each kind of exception path.  It's even  
fairly easy to read through the fast-path based on how it's laid out.


Let me point out a few problems with the C++ ways you've described of  
doing the same things:

(1)  You can't easily allocate and initialize an object in 2  
different steps.  In the kernel you want to be able to sleep in  
kmalloc to increase chances of getting the memory you need, but you  
may need to take a spinlock before actually initializing the data  
structure (say it's on a linked list).  If you split up the actual  
initialization into another function then you lose all of the  
advantages of C++ constructors.

(2)  Your code either adds a refcount for "item" or unconditionally  
releases it at the end of the function.  Yes that's fixable, but not  
in a way that preserves the exception-handling properties you're  
espousing so much.  When you get an exception, how does the code tell  
which objects to free and which ones not to?  (Answer: it can't,  
that's a semantic decision made by the programmer with "if" statements).

(3)  You still haven't explained how adding all sorts of implicit  
side effects is a good thing in an operating system kernel.

Cheers,
Kyle Moffett


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25 14:37           ` David Schwartz
@ 2006-04-25 19:50             ` Martin Mares
  2006-04-26  2:33               ` David Schwartz
  0 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-04-25 19:50 UTC (permalink / raw)
  To: David Schwartz; +Cc: Linux-Kernel@Vger. Kernel. Org

> 	Hahaha. So now, it's not good enough that they not ask you to do anything,
> they have to actively *prevent* you from choosing to waste time on their
> changes?

If you wish to interpret it that way, I won't prevent you :-)

Anyway -- what I meant is that even if somebody writes a patch changing
names to avoid collisions with C++, _merging_ such a patch could be
easily a waste of other people's time, especially when there is no
other advantage in merging such a patch (like if the reason is that
somebody wishes to port his closed-source driver to Linux [*]).

[*]: Not that I'm claiming that this is the case now, but it already
happened.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
First law of socio-genetics: Celibacy is not hereditary.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 19:22             ` Kyle Moffett
@ 2006-04-25 19:54               ` Michael Buesch
  2006-04-25 20:24               ` Avi Kivity
  1 sibling, 0 replies; 200+ messages in thread
From: Michael Buesch @ 2006-04-25 19:54 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Alan Cox, linux-kernel, Avi Kivity

[-- Attachment #1: Type: text/plain, Size: 2029 bytes --]

On Tuesday 25 April 2006 21:22, you wrote:
> Except they can't.  Lots and lots of bits of kernel code explicitly  
> depend on the fact that certain operations _cannot_ fail, and they  
> make that obvious through the fact that those functions don't have  
> any way of returning error conditions.

A function declared as
void foo(int bar) throw();
cannot fail or throw.

> >> First of all, that extra TakeLock object chews up stack, at least  
> >> 4 or 8 bytes of it, depending on your word size.
> >
> > No, it's optimized out. gcc notices that &lock doesn't change and  
> > that 'l' never escapes the function.
> 
> GCC does not notice that when you use out-of-line functions.  Let me  
> remind you that many of the kernel's spinlocks and other functions  
> are out-of-line, inlining them has significant performance penalties.

The TakeLock object is completely different from the actual
lock object. The TakeLock object does _only_ call
spin_lock() and spin_unlock(), which are still out of line.

> {
> 	int result;
> 	struct foo *item = kmalloc(sizeof(*item), GFP_KERNEL);
> 	if (unlikely(!item))
> 		return ERR_PTR(-ENOMEM);
> 	
> 	spin_lock(&item_lock);
> 	
> 	result = item_init(item, GFP_KERNEL);

scheduling while atomic ;)

> (1)  You can't easily allocate and initialize an object in 2  
> different steps.

That is not true. Google for "d-pointer" for an example
on how you might do this.

> (2)  Your code either adds a refcount for "item" or unconditionally  
> releases it at the end of the function.  Yes that's fixable, but not  
> in a way that preserves the exception-handling properties you're  
> espousing so much.  When you get an exception, how does the code tell  
> which objects to free and which ones not to?

By good design of the exception objects, which carry all needed
information when handling the exception.


I _don't- want to say, that C++ is good in the kernel.
My opinion is: C++ in the kernel is bad.

-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  9:09             ` Nikita Danilov
@ 2006-04-25 20:10               ` J.A. Magallon
  0 siblings, 0 replies; 200+ messages in thread
From: J.A. Magallon @ 2006-04-25 20:10 UTC (permalink / raw)
  To: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 1894 bytes --]

On Tue, 25 Apr 2006 13:09:47 +0400, Nikita Danilov <nikita@clusterfs.com> wrote:

> J.A. Magallon writes:
> 
> [...]
> 
>  > 
>  > Tell me what is the difference between:
>  > 
>  > 
>  >     sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
>  >     if (!sbi)
>  >         return -ENOMEM;
>  >     sb->s_fs_info = sbi;
>  >     memset(sbi, 0, sizeof(*sbi));
>  >     sbi->s_mount_opt = 0;
>  >     sbi->s_resuid = EXT3_DEF_RESUID;
>  >     sbi->s_resgid = EXT3_DEF_RESGID;
>  > 
>  > and
>  > 
>  >     SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>  >     {}
>  > 
>  >     ...
>  >     sbi = new SuperBlock;
>  >     if (!sbi)
>  >         return -ENOMEM;
>  > 
>  > apart that you don't get members initalized twice and get a shorter code :).
> 
> The difference is that second fragment doesn't mention GFP_KERNEL, so
> it's most likely wrong. Moreover it's shorter only because it places
> multiple initializations on the same like, hence, contradicting
> CodingStyle.
> 

Well, you could always have 

   sbi = new(GPF_KERNEL) SuperBlock;

And CodingStyle was written for C.

Just to make a thing clear: I'm not advocating to include C++ support in
current kernel. I just say that the only valid argument is that
'KERNEL IS C', and interfacing C with C++ just would add bloat and errors.
There is no technical argument to reject to write an OS kernel in C++.
It would not be slower not more complicated, and it will be probably safer
because it leaves less things (from thost you always _must_ do) to
programmers memories.

--
J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
werewolf!able!es                         \         It's better when it's free
Mandriva Linux release 2006.1 (Cooker) for i586
Linux 2.6.16-jam9 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Tue

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 16:46           ` Avi Kivity
  2006-04-25 17:10             ` Dmitry Torokhov
  2006-04-25 19:22             ` Kyle Moffett
@ 2006-04-25 20:11             ` Bongani Hlope
  2006-04-25 20:26               ` Avi Kivity
  2 siblings, 1 reply; 200+ messages in thread
From: Bongani Hlope @ 2006-04-25 20:11 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Alan Cox, linux-kernel

On Tuesday 25 April 2006 18:46, Avi Kivity wrote:
> Should you want to allocate from the heap, try this:
>
> {
>     spinlock_t::guard g(some_lock);
>     auto_ptr<Foo> item(new (gfp_mask) Foo);   /* or pass a kmem_cache_t */
>     item->do_something();
>     item->do_something_else();
>     return item.release();
> }
>

I love C++, but you have to stop it now. Imagine how many auto_ptr<Foo> will 
you use inside your kernel. The compiler will need to create a separete class 
for each. Using templates in the kernel will be plain silly.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  9:22                         ` Xavier Bestel
@ 2006-04-25 20:20                           ` J.A. Magallon
  2006-04-25 20:31                             ` Barry Kelly
  0 siblings, 1 reply; 200+ messages in thread
From: J.A. Magallon @ 2006-04-25 20:20 UTC (permalink / raw)
  To: Xavier Bestel, Linux-Kernel, 

[-- Attachment #1: Type: text/plain, Size: 2126 bytes --]

On Tue, 25 Apr 2006 11:22:32 +0200, Xavier Bestel <xavier.bestel@free.fr> wrote:

> 
> Yes, "if". With straight C, it's immediatly obvious the kmalloc() is the
> only function with side-effects and special requirements - an
> experienced hacker won't even look it up. With C++ those may be hidden
> behind each object or object member, that's the philosophy of the
> language. 
> The problem is that in kernel mode you must know precisely when and how
> you allocate memory.
> 

Don't mix allocation with initialization.
Well, lets see:

  struct xxx {
    struct yyy* y;
    int z;
  }
  
  xxx_init(struct xxx* x)
  {
     z = 0;
     y = kmalloc(GPF_KERNEL,sizeof(struct yyy));
     yyy_init(y);
  }

Now, if on other source file you read:
  ...
  struct xxx* x;
  x = kmallloc(GPF_KERNEL,sizeof(struct xxx));
  xxx_init(x);
  ..
  struct xxx  x2;
  xxx_init(&x2);

How do you know what xxx_init() does without looking at it ?
Cay you have just the allocation without init ? What happens if you forget it ?
What happens if you cut'n'paste from other driver and let something like

  struct xxx* x;
  x = kmallloc(GPF_KERNEL,sizeof(struct qqqqq));
  xxx_init(x);

The only difference it that
  x = new(GPF_KERNEL) XXX;

always does what it has to do correctly. What does XXX() constructor ?
You have to look at it, same as xxx_init().

As I said in other answer: I'm not advocating to include C++ support in
current kernel. I just say that the only valid argument is that
'KERNEL IS C', and interfacing C with C++ just would add bloat and errors.
There is no technical argument to reject to write an OS kernel in C++.
It would not be slower nor more complicated, and it will be probably safer
because it leaves less things (from thost you always _must_ do) to
programmers memories.

--
J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
werewolf!able!es                         \         It's better when it's free
Mandriva Linux release 2006.1 (Cooker) for i586
Linux 2.6.16-jam9 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Tue

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 19:22             ` Kyle Moffett
  2006-04-25 19:54               ` Michael Buesch
@ 2006-04-25 20:24               ` Avi Kivity
  1 sibling, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 20:24 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Alan Cox, linux-kernel

Kyle Moffett wrote:
>>
>> My experience with exceptions in kernel-like code (a distributed 
>> filesystem) was excellent.
>
> Well from all of the discussions about it that occurred on this list, 
> the biggest problem with exceptions in the kernel was the overhead to 
> keep track of the exception state and the try/catch stack.  
There is zero runtime overhead. In fact, code using exceptions is faster 
than the equivalent code using error returns.
> The other problem was handling exceptions in atomic contexts,
Can you elaborate? I don't see any special handling needed.
> in the guts of the scheduler,
That may or may not be tricky. The filesystem I worked on had it's own 
scheduler (in C++ :) but it was orders of magnitude simpler than the 
Linux scheduler.

I suspect thread creation and context switching need special handling, 
but I don't think the computational code needs anything.
> and in a host of other hot-paths.
The hotter the merrier!
>
>>> Which of the following shows the flow of code better?
>>
>> Once you accept the idea that an exception can occur (almost) anywhere
>
> Except they can't.  Lots and lots of bits of kernel code explicitly 
> depend on the fact that certain operations _cannot_ fail, and they 
> make that obvious through the fact that those functions don't have any 
> way of returning error conditions.
You can do that in C++ by indicating a function doesn't throw:

    void f() throw();
>
>> the C++ code shows you what the code does in the normal case without 
>> obfuscating it with error handling. Pretend that after every 
>> semicolon there is a comment of the form:
>>    /* possible exceptional return */
>
> As I pointed out before and seem doomed to point out again, this is an 
> _implicit_ piece of code, and in kernels implicit code is very very 
> bad.  Because of the varying contexts and close hardware dependence, 
> you want to explicitly state everything that happens.
This is possibly the core of our disagreement. I find that explicitly 
repeating the same code over and over again detracts from understanding.

And I disagree that proximity to hardware affects anything. I've written 
complete bringup code (from CPU reset to GUI) in C++ (in another 
life...). There is no problem programming memory controller registers 
and taking interrupts in C++.
>
>>> First of all, that extra TakeLock object chews up stack, at least 4 
>>> or 8 bytes of it, depending on your word size.
>>
>> No, it's optimized out. gcc notices that &lock doesn't change and 
>> that 'l' never escapes the function.
>
> GCC does not notice that when you use out-of-line functions.  Let me 
> remind you that many of the kernel's spinlocks and other functions are 
> out-of-line, inlining them has significant performance penalties.
Keep spin_lock() out of line and let spinlock_guard's constructor and 
destructor remain inline. Zero code size or performance hit.
>
>>> Secondly with standard integer error returns you have one or two 
>>> easily-predictable assembly instructions at each step of the way, 
>>> whereas with exceptions you trade the absence of error handling in 
>>> the rest of the code for a lot of extra instructions at the 
>>> exception throw and catch points.
>>
>> The extra code is out of line (not even an if (unlikely())). So yes, 
>> total code grows, but the exceptional paths can be in a 
>> .text.exception section and not consume cache or TLB space.
>
> Total bull.  Let me give you an example.  The following C++ code:
> {
>     Foo my_foo;
>     function_that_throws_exception();
> }
>
> Is turned by the compiler into a slight variant on this C code:
> {
>     Foo my_foo = Foo();
>     jmp_buf exception;
>     if (setjmp(exception))
>         goto out;
>     
>     function_that_throws_exception();
>     
> out:
>     ~Foo(&my_foo);
> }
>
> There is nothing about the above that the compiler can trivially 
> "out-of-line", not to mention the fact that you just royally screwed 
> the CPUs chances of getting branch prediction right.  There's the fact 
> that setjmp and longjmp are kind of hard in kernelspace.  Finally, the 
> stack usage is significantly increased, I think even in userspace, 
> jmp_buf occupies 8 longs (32 bytes) just for critical registers and 
> instruction pointer of the exception handler.  Also, the simplest case 
> of throwing an exception has turned from the three instructions "cmp 
> bnz ret" (compare result or pointer, branch to exception code, return) 
> to this mess:
> {
>     longjmp((int)pointer);
> }
>
> The longjmp function is simple, but not _that_ simple, and it still 
> breaks branch prediction in a bad way.
setjmp()/longjmp() (or equivalents) are not used for exception handling 
on Linux.

what _actually_ happens is that when an exception is thrown, the 
exeption handling mechanism rolls back the stack and figures out the 
program counter where we're due to return, and consults an out-of-line 
table which tells it which destructors to execute. Something like this:

{
    Foo my_foo = Foo();
e1:
   function_that_throws_exception();
e2:
   my_foo.~Foo();
}

/* begin out-of-line code */
exception_table[] = {
    [e1] : h1
    [e2]: h2
}

{
h2:
    my_foo.~Foo();
h1:
}
>>
>> In C++ you just have to treat declarations as executable statements. 
>> Just as you can't compile the code with a C compiler, you can't read 
>> it with a C mindset. Once you get used to it, it isn't surprising at 
>> all.
>
> That's all well and good, until you assume that "some_type foo = 3;" 
> is just declaring an integer through a typedef instead of declaring an 
> object with side effects.  The thing about the linux kernel is that 
> basically _nobody_ understands all of it, and as a result each and 
> every bit of code must stand on its own and be fairly obvious as to 
> side effects and such.  In C++, most of the language features are 
> designed to _hide_ those side effects and as a result it's a terrible 
> fit for the kernel.
>
So don't assume it, or forbid (through CodingStyle) constructors with 
single integer parameters.
>>> Let me point out _again_ how unobvious and fragile the flow of code 
>>> there is.  Not to mention the fact that the C++ compiler can easily 
>>> notice that item1 and item2 are never used and optimize them out 
>>> entirely.
>>
>> Excellent! If there are no side effects, I want it out. If there are 
>> side effects, it won't optimize them out.
>
> How can it tell?  You aren't writing all your member functions inline, 
> are you?
When they're empty, sure. Or when they're one liners. Or when I know 
they have no side effects.

This isn't any different from C or existing kernel practice.
>
>>>   You also totally missed the "int flags" argument you're supposed 
>>> to pass to object specifying allocation parameters,
>>
>> There is no allocation here (both the C and the C++ code allocate on 
>> the stack.
>
> Let's look in the kernel.  How often do you find non-trivial 
> constructor functions that _don't_ allocate memory, hm?
So it was a bad example. The point is it was much simpler compared to 
the equivalent C. And the more complex it gets, the more pronounced the 
difference is.
>
>> Should you want to allocate from the heap, try this:
>>
>> {
>>    spinlock_t::guard g(some_lock);
>>    auto_ptr<Foo> item(new (gfp_mask) Foo);   /* or pass a 
>> kmem_cache_t */
>>    item->do_something();
>>    item->do_something_else();
>>    return item.release();
>> }
>
> I think this code speaks for itself about its lack of readability.
Maybe for a C reader. For a C++ reader it's quite clear.

>
>>    if ((r = foo_do_something(item))) {
>
> Your kernel-idiomatic C is terrible.  Please don't go around writing 
> much kernel code in this style, that's disgusting.  Your 
> multiply-duplicated return statements were also bad form, see my 
> example for a much clearer way of doing it.
You can tweak the style however you like. The C code wil end up longer 
and with more paths to examine, just doing boilerplate stuff.

We should concentrate on the problem, not boilerplate.
>
>>> Yeah, sure, yours is 3 lines when you omit the following:
>>> (1)  Handling allocation flags like GFP_KERNEL
>> done
>
> And unreadable afterwards
>
>>> (4)  Reference counting, garbage collection, or another way to 
>>> selectively free the allocated objects based on success or failure 
>>> of other code.
>> Reference counting is ridiculously to do in C++. I'll spare you the 
>> details.
>
> I'll assume you mean "ridiculously easy" there.  The problem is that 
> with the exception handling system you add refcounts to a lot of 
> objects that don't need them.  Here's an example that doesn't need a 
> refcount.  I'm registering the "item" with a subsystem, and if that 
> fails the object is immediately freed.
You seem to assyme that C++ is forcing you into a stranglehold. It 
isn't. It gives you tools, you choose how and when to use them. You can 
even write straight C with all the paths spelled out in glorious detail.
>
> {
>     int result;
>     struct foo *item = kmalloc(sizeof(*item), GFP_KERNEL);
>     if (unlikely(!item))
>         return ERR_PTR(-ENOMEM);
>     
>     spin_lock(&item_lock);
>     
>     result = item_init(item, GFP_KERNEL);
>     if (unlikely(result))
>         goto free;
>     
>     result = item_register(subsystem, item);
>     if (unlikely(result))
>         goto destroy;
>     
> out:
>     spin_unlock(&item_lock);
>     return result;
>
>     /* Error handling */
> destroy:
>     item_destroy(item);
> free:
>     kfree(item);
>     goto out;
> }
>
Here's the C++ code:

(I'm assuming you want item_init() out of the spinlock since you pass it 
GFP_KERNEL, presumably for its internal allocations. I'm also assuming 
the function returns 0 or error)

{
    auto_ptr<foo> item = new (GFP_KERNEL) foo(GFP_KERNEL);
    spinlock_t::guard guard(item_lock);
    item->register(subsystem);
    item.release();
}

(and no, auto_ptr<> does not reference count)

This is a translation of what you wrote. 19 lines vs 4.
   
   
> Please note that the assembly into which this optimizes is quite 
> efficient, the compiler can trivially order the fast-path and place 
> all of the exception code after the function or could theoretically 
> even put it in a different section.  The side-effects are quite 
> obvious, and it's also simple to identify exactly how many 
> instructions this function costs; there's a memory allocation, a lock, 
> and two function calls.  Interspersed in there are exactly 3 
> conditional jumps to exception-handling code.  Direct stack usage for 
> this function is around 8 or 12 bytes, depending on word size.
The assembly into which the C++ code is even more optimal (at the 
expense of the exceptional case). Direct stack usage is 4 or 8 bytes, 
depending on word size, unless foo::register is inlined, in which case 
usage drops to zero.
>
> The biggest advantage to this method is that we can tell C exactly 
> what exceptions we expect from the various functions.  Not only that, 
> but we already know what type they are, how likely they are to occur, 
> and exactly how to handle each kind of exception path.  It's even 
> fairly easy to read through the fast-path based on how it's laid out.
>
That's also the biggest disadvantage. You have to wade through 19 lines 
of code, 15 of which should have been generated by the compiler. You're 
following a template; that's a job for machines, not humans.

Modifying those 19 lines won't be fun, either, say you add a 
mutex_lock() at the beginning, now you have to mutex_unlock() in two 
separate places or rework the error paths. That's the stuff 2.6.18.9s 
are made of.

On my example, you add one line to the beginning.
>
> Let me point out a few problems with the C++ ways you've described of 
> doing the same things:
>
> (1)  You can't easily allocate and initialize an object in 2 different 
> steps.
You can. Again, C++ doesn't force you to do anything:

    auto_ptr<foo> item = new (GFP_KERNEL) foo();
    spinlock_t::guard guard(item_lock);
    item->init(...);
>   In the kernel you want to be able to sleep in kmalloc to increase 
> chances of getting the memory you need, but you may need to take a 
> spinlock before actually initializing the data structure (say it's on 
> a linked list).  If you split up the actual initialization into 
> another function then you lose all of the advantages of C++ constructors.
>
Tradeoffs, tradeoffs. but you still get the destructor to clean up, and 
auto_ptr to free memory on exception.
> (2)  Your code either adds a refcount for "item" or unconditionally 
> releases it at the end of the function.  Yes that's fixable, but not 
> in a way that preserves the exception-handling properties you're 
> espousing so much.  When you get an exception, how does the code tell 
> which objects to free and which ones not to?  (Answer: it can't, 
> that's a semantic decision made by the programmer with "if" statements).
Sorry, that's based on a wrong understanding of what auto_ptr<> is. It 
has nothing to do with refcounts.

The code is just a translation of what you wrote.
>
> (3)  You still haven't explained how adding all sorts of implicit side 
> effects is a good thing in an operating system kernel.
Reducing code size, improving performance, and reducing bug count. All 
of which, I believe, are important to Linux.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 20:11             ` Bongani Hlope
@ 2006-04-25 20:26               ` Avi Kivity
  2006-04-25 21:02                 ` Valdis.Kletnieks
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 20:26 UTC (permalink / raw)
  To: Bongani Hlope; +Cc: Kyle Moffett, Alan Cox, linux-kernel

Bongani Hlope wrote:
> On Tuesday 25 April 2006 18:46, Avi Kivity wrote:
>   
>> Should you want to allocate from the heap, try this:
>>
>> {
>>     spinlock_t::guard g(some_lock);
>>     auto_ptr<Foo> item(new (gfp_mask) Foo);   /* or pass a kmem_cache_t */
>>     item->do_something();
>>     item->do_something_else();
>>     return item.release();
>> }
>>
>>     
>
> I love C++, but you have to stop it now. Imagine how many auto_ptr<Foo> will 
> you use inside your kernel. The compiler will need to create a separete class 
> for each. Using templates in the kernel will be plain silly.
>   
auto_ptr<>'s are fully inlined so their impact is nil.

(And actually I dislike C++, it only looks good next to C)

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25  9:06         ` Matt Keenan
@ 2006-04-25 20:29           ` Bongani Hlope
  2006-04-25 20:37             ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Bongani Hlope @ 2006-04-25 20:29 UTC (permalink / raw)
  To: Matt Keenan; +Cc: Avi Kivity, LKML

On Tuesday 25 April 2006 11:06, Matt Keenan wrote:
> Avi Kivity wrote:
> >
> > Maybe not mathematically, but I can try to hand-wave my way through.
> >
> > By using exceptions, you free the normal return paths from having to
> > check for errors. The exception paths can be kept in a dedicated
> > section, avoiding cache pollution. The total code (and data) size
> > increases, but the non-exception paths size decreases significantly
> > and becomes faster.
> >
> > Using C++ objects instead of C objects allows you to avoid void
> > pointers, which are difficult for the compiler to optimize due to
> > aliasing.
>
> Exception handling on a kernel with a 4K stack would be very
> interesting, now imagine what would happen if one exception triggered
> another? and possibly another?? And even giving up on the stack issues,
> what about cacheline / performance issues? Moving error handling even
> further from the fast path isn't going to help performance much.. How
> about an exception for every ENOENT? Have you seen how many ENOENT's
> /lib/ld-linux.so.2 generates when a large app starts? Take firefox, load
> it, let it open five tabs, then shut it down. On my system, 1377
> open()'s, 527 of which are ENOENT, 135 of those before the program has
> finished linking. Not exactly the best way to speed the system up. And
> don't say you can use the dentry cache to return an object or NULL, as
> this is just replication of what C does, but with even more syntatic
> goop. C++ is a good tool, for the right job. The kernel is not one of them.
>

To enable stack unwinding for exception handling, extra exception-related 
information about each function needs to be available for each stack frame. 
This information describes which destructors need to be called (so that local 
objects can be cleaned up), indicates whether the current function has a try 
block, and lists which exceptions the associated catch clauses can handle.

Take a look at a typical OOPS trace and tell me if that will fit in a 4k stack 
with C++ and stack unwinding.

---
    Choose the right tools, use them the right way. 
     Refuse to compromise, expect  to succeed, 
                      Then start again.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25 20:20                           ` J.A. Magallon
@ 2006-04-25 20:31                             ` Barry Kelly
  0 siblings, 0 replies; 200+ messages in thread
From: Barry Kelly @ 2006-04-25 20:31 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Xavier Bestel, Linux-Kernel, 

On Tue, 25 Apr 2006 22:20:26 +0200, "J.A. Magallon" <jamagallon@able.es>
wrote:

> There is no technical argument to reject to write an OS kernel in C++.
> It would not be slower nor more complicated, and it will be probably safer
> because it leaves less things (from thost you always _must_ do) to
> programmers memories.

In a pageable kernel, it would be harder to guarantee that virtual
methods' code is paged in while locks that govern the VM are held.

Of course you could get the same problem with C and pointers to functions,
but at least you could probe them explicitly. With C++, the vtable is one
step removed.

-- Barry

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 20:29           ` Bongani Hlope
@ 2006-04-25 20:37             ` Avi Kivity
  2006-04-25 21:08               ` Bongani Hlope
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 20:37 UTC (permalink / raw)
  To: Bongani Hlope; +Cc: Matt Keenan, LKML

Bongani Hlope wrote:
> To enable stack unwinding for exception handling, extra exception-related 
> information about each function needs to be available for each stack frame. 
> This information describes which destructors need to be called (so that local 
> objects can be cleaned up), indicates whether the current function has a try 
> block, and lists which exceptions the associated catch clauses can handle.
>
> Take a look at a typical OOPS trace and tell me if that will fit in a 4k stack 
> with C++ and stack unwinding.
>
>   
C++ on Linux does not put any information on the stack for exception 
handling purposes. Windows implementations do that but (a) I think the 
Windows kernel has a 12K stack (b) Linux is unlikely to use the 
Microsoft C++ compiler.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 20:26               ` Avi Kivity
@ 2006-04-25 21:02                 ` Valdis.Kletnieks
  2006-04-25 21:15                   ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Valdis.Kletnieks @ 2006-04-25 21:02 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Bongani Hlope, Kyle Moffett, Alan Cox, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 225 bytes --]

On Tue, 25 Apr 2006 23:26:17 +0300, Avi Kivity said:

> auto_ptr<>'s are fully inlined so their impact is nil.

Except for the punishment the i-cache takes.  There's reasons why we
fight over "to inline or not to inline"....

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 20:37             ` Avi Kivity
@ 2006-04-25 21:08               ` Bongani Hlope
  0 siblings, 0 replies; 200+ messages in thread
From: Bongani Hlope @ 2006-04-25 21:08 UTC (permalink / raw)
  To: Avi Kivity; +Cc: LKML

On Tuesday 25 April 2006 22:37, Avi Kivity wrote:
> Bongani Hlope wrote:
> > To enable stack unwinding for exception handling, extra exception-related
> > information about each function needs to be available for each stack
> > frame. This information describes which destructors need to be called (so
> > that local objects can be cleaned up), indicates whether the current
> > function has a try block, and lists which exceptions the associated catch
> > clauses can handle.
> >
> > Take a look at a typical OOPS trace and tell me if that will fit in a 4k
> > stack with C++ and stack unwinding.
>
> C++ on Linux does not put any information on the stack for exception
> handling purposes. Windows implementations do that but (a) I think the
> Windows kernel has a 12K stack (b) Linux is unlikely to use the
> Microsoft C++ compiler.

Cool thanx, I see that g++ (3,x) uses Dwarf2 to store the frame info. Unlike 
Microsoft.

---
    Choose the right tools, use them the right way. 
     Refuse to compromise, expect  to succeed, 
                      Then start again.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 21:02                 ` Valdis.Kletnieks
@ 2006-04-25 21:15                   ` Avi Kivity
       [not found]                     ` <71a0d6ff0604251646g4fc90b3dr30a03b8606360e7f@mail.gmail.com>
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-25 21:15 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: Bongani Hlope, Kyle Moffett, Alan Cox, linux-kernel

Valdis.Kletnieks@vt.edu wrote:
>
> On Tue, 25 Apr 2006 23:26:17 +0300, Avi Kivity said:
>
> > auto_ptr<>'s are fully inlined so their impact is nil.
>
> Except for the punishment the i-cache takes.  There's reasons why we
> fight over "to inline or not to inline"....
>
Not in this case. The constructor is an assignment. The destructor is an 
if () followed by a delete. In this case, the if () is optimized away so 
you are left with less generated code than the C case, for the 
non-exceptional path.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-25 19:50             ` Martin Mares
@ 2006-04-26  2:33               ` David Schwartz
  2006-04-26  3:42                 ` Matthew Frost
  0 siblings, 1 reply; 200+ messages in thread
From: David Schwartz @ 2006-04-26  2:33 UTC (permalink / raw)
  To: Linux-Kernel@Vger. Kernel. Org


> > Hahaha. So now, it's not good enough that they not ask you
> > to do anything,
> > they have to actively *prevent* you from choosing to waste time on their
> > changes?

> If you wish to interpret it that way, I won't prevent you :-)

> Anyway -- what I meant is that even if somebody writes a patch changing
> names to avoid collisions with C++, _merging_ such a patch could be
> easily a waste of other people's time, especially when there is no
> other advantage in merging such a patch (like if the reason is that
> somebody wishes to port his closed-source driver to Linux [*]).

> [*]: Not that I'm claiming that this is the case now, but it already
> happened.

	You are being ambiguous here, possibly deliberately possibly through honest
confusion and possibly because you know what you're saying and can't imagine
how anyone else could not understand you. For example, does "merging" mean
the process of making the kernel continue to compile cleanly with the patch
applied? Or does "merging" mean the effort in maintaining your current level
of understanding and proficiency with the kernel once the patch is in the
mainline?

	If the former, you are totally correct. Nobody should work on merging a
patch they don't believe in. If the latter, then see my criticism.

	You originally said:

>>> As far as they intend to stay away from the main kernel tree, I don't
>>> critize anybody. But for example renaming otherwise logically
>>> named structure
>>> members (`class' etc.) just for C++ compatibility _IS_ wasting time of
>>> other people, who need to remember new names, review the patch and so
on.

	If you don't believe the patch will benefit anyone, the review shouldn't
take you more than a second or two. You should definitely say "I don't
believe in this patch, I don't like C++ in the kernel, my review is that it
should not go in" and that's it. Nobody is forcing you to work to adopt
changes you don't believe in, and you should *not* do so as your part in
keeping kernel code quality high.

	As for remembering new names, that's a load of complete crap and I find it
hard to believe that you're raising the argument for honest reasons.

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-26  2:33               ` David Schwartz
@ 2006-04-26  3:42                 ` Matthew Frost
  2006-04-26 19:25                   ` David Schwartz
  0 siblings, 1 reply; 200+ messages in thread
From: Matthew Frost @ 2006-04-26  3:42 UTC (permalink / raw)
  To: davids, linux-kernel



--- David Schwartz <davids@webmaster.com> wrote:

> 
> > > Hahaha. So now, it's not good enough that they not ask you
> > > to do anything,
> > > they have to actively *prevent* you from choosing to waste time on
> their
> > > changes?
> 
> > If you wish to interpret it that way, I won't prevent you :-)
> 
> > Anyway -- what I meant is that even if somebody writes a patch
> changing
> > names to avoid collisions with C++, _merging_ such a patch could be
> > easily a waste of other people's time, especially when there is no
> > other advantage in merging such a patch (like if the reason is that
> > somebody wishes to port his closed-source driver to Linux [*]).
> 
> > [*]: Not that I'm claiming that this is the case now, but it already
> > happened.
> 
> 	You are being ambiguous here, possibly deliberately possibly 
> through honest confusion and possibly because you know what you're 
> saying and can't imagine how anyone else could not understand you. For 
> example, does "merging" mean the process of making the kernel continue 
> to compile cleanly with the patch applied? Or does "merging" mean the 
> effort in maintaining your current level of understanding and 
> proficiency with the kernel once the patch is in the mainline?
> 

How long have you been paying attention here?  0) You're pushing a
non-starter, rudely, and ignoring the pushback, and 1) you don't know how
 patches get merged into mainline.

Merging does involve pretty much all of that.  In consideration of a
patch or patch set for merging, its benefit to the kernel, compliance
with coding standards for the kernel, ease of maintenance of the whole
kernel by a vast, far-flung community of developers after the patch goes
in, the quality of the code, and how nicely its author plays with others
are taken into account.  Patches become part of the kernel.  Patches
belong to everybody once they're accepted, and they have to be workable
for anybody that might have to touch the systems they modify.  If you
rename vast parts of the kernel for no reason other than your wish to
have C++ work in it, you screw up everybody.  Naming is important.

> 	If the former, you are totally correct. Nobody should work on 
> merging a patch they don't believe in. If the latter, then see my 
> criticism.

It isn't about belief.  It's about code.  In point of fact, it isn't even
about you until you become such an irritant that your personality makes
people shy away from your patches.  It is about working well in the
pre-existing structure.  Minimal, focused changes that achieve one goal
per patch, that can be proven useful.

> 
> 	You originally said:
> 
>> As far as they intend to stay away from the main kernel tree, I
>> don't critize anybody. But for example renaming otherwise logically
>> named structure members (`class' etc.) just for C++ compatibility _IS_
>> wasting time of other people, who need to remember new names, review 
>> the patch and so on.
> 
> 	If you don't believe the patch will benefit anyone, the review
> shouldn't take you more than a second or two. You should definitely say
> "I don't believe in this patch, I don't like C++ in the kernel, my 
> review is that it should not go in" and that's it. Nobody is forcing
you
> to work to adopt changes you don't believe in, and you should *not* do 
> so as your part in keeping kernel code quality high.

You are partially correct.  Nobody forces anybody to review or accept a
patch that they believe is in bad taste, or is malformed, or will do Bad
Things to the kernel.  You may, at your discretion, submit all of the
patches you wish to this list, or to Linus, or to Andrew, or anyone you
like.  Should they be for the purpose of converting functioning kernel C
into what you think ought to be functional C++, I can practically
guarantee they will go absolutely nowhere.  

$ cat convert_kernel_to_c++.patch >/dev/null 

would be faster.  You may think of it as pearls before swine if it makes
you feel better, but the kernel devs are being rational.

> 
> 	As for remembering new names, that's a load of complete crap and I
> find it hard to believe that you're raising the argument for honest 
> reasons.
> 

The scale of the kernel, the number and churn of developers, and the
importance of not breaking things in a stable kernel tend to argue
against you.  Humans develop the kernel.  Humans remember names well. 
You may think that's arbitrary, but when you change naming across the
entire kernel, you confuse a very large and diverse group of people who
do this because they enjoy it.  It's hard enough when this has to happen
for useful or necessary reasons; you're asking the kernel developers to
accept it for a completely arbitrary whim that they have rejected
successfully several times in the past.  You want C++?  Fork the freely
available source code at a convenient point and convert it yourself.  As
long as it stays GPL, you're perfectly within your rights so to do. 
Hobson's choice is yours.  Belaboring this point is silly.

MAF


> 	DS
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel"
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
       [not found]                     ` <71a0d6ff0604251646g4fc90b3dr30a03b8606360e7f@mail.gmail.com>
@ 2006-04-26  4:39                       ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-26  4:39 UTC (permalink / raw)
  To: Alexander Shishckin
  Cc: Valdis.Kletnieks, Bongani Hlope, Kyle Moffett, Alan Cox, linux-kernel

Alexander Shishckin wrote:
> On 4/26/06, Avi Kivity <avi@argo.co.il> wrote:
>   
>> Not in this case. The constructor is an assignment. The destructor is an
>> if () followed by a delete. In this case, the if () is optimized away so
>> you are left with less generated code than the C case, for the
>> non-exceptional path.
>>     
> Relying on compiler optimisations is just as well stupid as hunting
> trialing writespaces in a dark room miles away.
>   

It'd like to see the output of 'size vmlinux' with optimizations turned 
off. The kernel is full of forwarding functions and constructs that 
optimize away to nothing.

Last time I tried, the kernel wouldn't even compile at -O0, but that may 
have changed with the always_inline work.

And it is *not relying* on compiler optimizations that is stupid. It 
means you're throwing away the work of the compiler folk, and doing it 
instead *by hand* at every piece of code you write.

> It's almost about time to quit this thread and show us some code that
> works. (Forked from 2.6.16, bootable on an average amount of
> architectures...)
>   

Ha ha.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:54                 ` linux-os (Dick Johnson)
@ 2006-04-26  8:30                   ` Jan Engelhardt
  2006-04-26 11:36                     ` linux-os (Dick Johnson)
  0 siblings, 1 reply; 200+ messages in thread
From: Jan Engelhardt @ 2006-04-26  8:30 UTC (permalink / raw)
  To: linux-os (Dick Johnson)
  Cc: Avi Kivity, dtor_core, Kyle Moffett, Alan Cox, linux-kernel


>Class Kernel

Syntax error. Needs to be "class".

>{
>public:
>     virtual void starter(Scheduler *current) = 0x00;
>};
>
>Okay, I just started your new C++ kernel! Please send email when it
>is done. I will help test it.
>

Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-26  8:30                   ` Jan Engelhardt
@ 2006-04-26 11:36                     ` linux-os (Dick Johnson)
  0 siblings, 0 replies; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-26 11:36 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: Avi Kivity, dtor_core, Kyle Moffett, Alan Cox, linux-kernel


On Wed, 26 Apr 2006, Jan Engelhardt wrote:

>
>> Class Kernel
>
> Syntax error. Needs to be "class".
>
>> {
>> public:
>>     virtual void starter(Scheduler *current) = 0x00;
>> };
>>
>> Okay, I just started your new C++ kernel! Please send email when it
>> is done. I will help test it.
>>
>
> Jan Engelhardt
> --

Ooops! Got me. I'll recompile and see if it boots!


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
Warning : 98.36% of all statistics are fiction, book release in April.
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-26  3:42                 ` Matthew Frost
@ 2006-04-26 19:25                   ` David Schwartz
  2006-04-26 20:01                     ` Jan-Benedict Glaw
                                       ` (3 more replies)
  0 siblings, 4 replies; 200+ messages in thread
From: David Schwartz @ 2006-04-26 19:25 UTC (permalink / raw)
  To: linux-kernel


> > 	As for remembering new names, that's a load of complete crap and I
> > find it hard to believe that you're raising the argument for honest
> > reasons.

> The scale of the kernel, the number and churn of developers, and the
> importance of not breaking things in a stable kernel tend to argue
> against you.  Humans develop the kernel.  Humans remember names well.
> You may think that's arbitrary, but when you change naming across the
> entire kernel, you confuse a very large and diverse group of people who
> do this because they enjoy it.  It's hard enough when this has to happen
> for useful or necessary reasons; you're asking the kernel developers to
> accept it for a completely arbitrary whim that they have rejected
> successfully several times in the past.

	C++ has how many additional reserved words? I believe the list is delete,
friend, private, protected, public, template, throw, try, and catch.
Renaming every symbol that currently has a name from this list to the
corresponding name with a trailing underscore is an easily understood
consistent change.

	That you would argue against is with things like "not breaking things" is a
load of complete crap.

> You want C++?  Fork the freely
> available source code at a convenient point and convert it yourself.  As
> long as it stays GPL, you're perfectly within your rights so to do.
> Hobson's choice is yours.  Belaboring this point is silly.

	Making ridiculous arguments like that a consistent change of a small set of
names is "breaking things in a stable kernel" is silly.

	And, FWIW, it isn't even necessary to change those names. That is only
needed to compile the kernel in C++, which is not what anyone was talking
about. Supporting C++ modules, for example, would work fine even if the
kernel had variables called 'class' or 'private'. (Though things could be
done a lot more cleanly if it didn't as it would require some remapping
before and after compilation.)

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 19:25                   ` David Schwartz
@ 2006-04-26 20:01                     ` Jan-Benedict Glaw
  2006-04-26 20:09                       ` Linus Torvalds
  2006-04-26 20:05                     ` linux-os (Dick Johnson)
                                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ messages in thread
From: Jan-Benedict Glaw @ 2006-04-26 20:01 UTC (permalink / raw)
  To: linux-kernel; +Cc: David Schwartz

[-- Attachment #1: Type: text/plain, Size: 1581 bytes --]

On Wed, 2006-04-26 12:25:19 -0700, David Schwartz <davids@webmaster.com> wrote:
[Variable names that are reserved in C++]
> 	And, FWIW, it isn't even necessary to change those names. That is only
> needed to compile the kernel in C++, which is not what anyone was talking
> about. Supporting C++ modules, for example, would work fine even if the
> kernel had variables called 'class' or 'private'. (Though things could be
> done a lot more cleanly if it didn't as it would require some remapping
> before and after compilation.)

There's one _practical_ thing you need to keep in mind: you'll either
need 'C++'-clean kernel headers (to interface low-level kernel
functions) or a separate set of headers.

For separate headers, I see the problem of keeping them synchronized
with the kernel. The clean-up-kernel-headers-for-userspce-consumption
guys already took that bullet once and up to now, there's no "real"
result. (That's while we all know that kernel values *are* somewhat
for the userspace guys:-)  I see an even smaller user-base for
separate C++ kernel headers (and thus more work per person)--and I
think that the current in-kernel headers just won't be C++ compatible,
ever[*].

MfG, JBG
[*] Famous last words...

-- 
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 für einen Freien Staat voll Freier Bürger"  | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-26 19:25                   ` David Schwartz
  2006-04-26 20:01                     ` Jan-Benedict Glaw
@ 2006-04-26 20:05                     ` linux-os (Dick Johnson)
  2006-04-26 20:09                     ` Xavier Bestel
  2006-04-26 21:05                     ` Martin Mares
  3 siblings, 0 replies; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-26 20:05 UTC (permalink / raw)
  To: David Schwartz; +Cc: linux-kernel


On Wed, 26 Apr 2006, David Schwartz wrote:

>
>>> 	As for remembering new names, that's a load of complete crap and I
>>> find it hard to believe that you're raising the argument for honest
>>> reasons.
>
>> The scale of the kernel, the number and churn of developers, and the
>> importance of not breaking things in a stable kernel tend to argue
>> against you.  Humans develop the kernel.  Humans remember names well.
>> You may think that's arbitrary, but when you change naming across the
>> entire kernel, you confuse a very large and diverse group of people who
>> do this because they enjoy it.  It's hard enough when this has to happen
>> for useful or necessary reasons; you're asking the kernel developers to
>> accept it for a completely arbitrary whim that they have rejected
>> successfully several times in the past.
>
> 	C++ has how many additional reserved words? I believe the list is delete,
> friend, private, protected, public, template, throw, try, and catch.
> Renaming every symbol that currently has a name from this list to the
> corresponding name with a trailing underscore is an easily understood
> consistent change.
>
> 	That you would argue against is with things like "not breaking things" is a
> load of complete crap.
>
>> You want C++?  Fork the freely
>> available source code at a convenient point and convert it yourself.  As
>> long as it stays GPL, you're perfectly within your rights so to do.
>> Hobson's choice is yours.  Belaboring this point is silly.
>
> 	Making ridiculous arguments like that a consistent change of a small set of
> names is "breaking things in a stable kernel" is silly.
>
> 	And, FWIW, it isn't even necessary to change those names. That is only
> needed to compile the kernel in C++, which is not what anyone was talking
> about. Supporting C++ modules, for example, would work fine even if the
> kernel had variables called 'class' or 'private'. (Though things could be
> done a lot more cleanly if it didn't as it would require some remapping
> before and after compilation.)
>
> 	DS


You know. All one needs to do is to compile C++ module code outside
the kernel. I compile such code outside the kernel all the time.

You make make your own private header directory that contains the
few modified kernel headers that you need. You put this directory
first in the -I(SearchList) on the command-line so that the "bad"
kernel headers are never even found.

Then you make a kernel module with C++. Remember that you can't
include your C++ runtime library on stuff that runs inside the
kernel. I think that, just to access the "struct file" structure,
which is fairly important for modules, you are going to need
'C' wrappers around your C++ code. Once you get something to actually
load IFF you get it to load, you will probably find that most
of your code is wrappers, which don't disappear. They are essential
conversion procedures.

After a few days of capture the Stockholm syndrome person will probably
understand that C++ was not designed for operating system kernels.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
Warning : 98.36% of all statistics are fiction, book release in April.
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 20:01                     ` Jan-Benedict Glaw
@ 2006-04-26 20:09                       ` Linus Torvalds
  2006-04-26 20:19                         ` Al Viro
                                           ` (3 more replies)
  0 siblings, 4 replies; 200+ messages in thread
From: Linus Torvalds @ 2006-04-26 20:09 UTC (permalink / raw)
  To: Jan-Benedict Glaw; +Cc: linux-kernel, David Schwartz



On Wed, 26 Apr 2006, Jan-Benedict Glaw wrote:
> 
> There's one _practical_ thing you need to keep in mind: you'll either
> need 'C++'-clean kernel headers (to interface low-level kernel
> functions) or a separate set of headers.

I suspect it would be easier to just do

	extern "C" {
	#include <linux/xyz.h>
	...
	}

instead of having anything really C++'aware in the headers.

If by "clean" you meant that the above works, then yeah, there might be 
_some_ cases where we use C++ keywords etc in the headers, but they should 
be pretty unusual and easy to fix.

The real problem with C++ for kernel modules is:

 - the language just sucks. Sorry, but it does.
 - some of the C features we use may or may not be usable from C++ 
   (statement expressions?)
 - the compilers are slower, and less reliable. This is _less_ of an issue 
   these days than it used to be (at least the reliability part), but it's 
   still true.
 - a lot of the C++ features just won't be supported sanely (ie the kernel 
   infrastructure just doesn't do exceptions for C++, nor will it run any 
   static constructors etc).

Anyway, it should all be doable. Not necessarily even very hard. But I 
doubt it's worth it.

		Linus

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-26 19:25                   ` David Schwartz
  2006-04-26 20:01                     ` Jan-Benedict Glaw
  2006-04-26 20:05                     ` linux-os (Dick Johnson)
@ 2006-04-26 20:09                     ` Xavier Bestel
  2006-04-26 20:44                       ` Randy.Dunlap
  2006-04-27  7:49                       ` C++ pushback Jiri Kosina
  2006-04-26 21:05                     ` Martin Mares
  3 siblings, 2 replies; 200+ messages in thread
From: Xavier Bestel @ 2006-04-26 20:09 UTC (permalink / raw)
  To: davids; +Cc: linux-kernel

Le mercredi 26 avril 2006 à 12:25 -0700, David Schwartz a écrit :

> 	C++ has how many additional reserved words? I believe the list is delete,
> friend, private, protected, public, template, throw, try, and catch.

You forgot namespace, mutable, new, class, const_cast, dynamic_cast,
static_cast, reinterpret_cast, explicit, true, false, operator, typeid,
typename and virtual. Maybe I forgot some (interface ?). Probably some
new ones will appear.

	Xav



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 20:09                       ` Linus Torvalds
@ 2006-04-26 20:19                         ` Al Viro
  2006-04-26 21:37                           ` Sam Ravnborg
  2006-04-26 20:25                         ` Jan-Benedict Glaw
                                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ messages in thread
From: Al Viro @ 2006-04-26 20:19 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jan-Benedict Glaw, linux-kernel, David Schwartz

On Wed, Apr 26, 2006 at 01:09:38PM -0700, Linus Torvalds wrote:
> The real problem with C++ for kernel modules is:
> 
>  - the language just sucks. Sorry, but it does.
>  - some of the C features we use may or may not be usable from C++ 
>    (statement expressions?)
>  - the compilers are slower, and less reliable. This is _less_ of an issue 
>    these days than it used to be (at least the reliability part), but it's 
>    still true.
>  - a lot of the C++ features just won't be supported sanely (ie the kernel 
>    infrastructure just doesn't do exceptions for C++, nor will it run any 
>    static constructors etc).

   - a lot of C++ advocates agree that some subset could be used sanely,
     but there's no agreement as to _which_ subset would that be.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 20:09                       ` Linus Torvalds
  2006-04-26 20:19                         ` Al Viro
@ 2006-04-26 20:25                         ` Jan-Benedict Glaw
  2006-04-26 20:43                         ` David Schwartz
  2006-04-26 23:00                         ` Roman Kononov
  3 siblings, 0 replies; 200+ messages in thread
From: Jan-Benedict Glaw @ 2006-04-26 20:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, David Schwartz

[-- Attachment #1: Type: text/plain, Size: 1972 bytes --]

On Wed, 2006-04-26 13:09:38 -0700, Linus Torvalds <torvalds@osdl.org> wrote:
> On Wed, 26 Apr 2006, Jan-Benedict Glaw wrote:
> > There's one _practical_ thing you need to keep in mind: you'll either
> > need 'C++'-clean kernel headers (to interface low-level kernel
> > functions) or a separate set of headers.
> 
> I suspect it would be easier to just do
> 
> 	extern "C" {
> 	#include <linux/xyz.h>
> 	...
> 	}
> 
> instead of having anything really C++'aware in the headers.

...but you need to admit that your left hand tried to make your right
hand not typing this, didn't it?

>  - the language just sucks. Sorry, but it does.
>  - some of the C features we use may or may not be usable from C++ 
>    (statement expressions?)

In the constructor pathes, I expect higher stack usage than we now
have.

>  - a lot of the C++ features just won't be supported sanely (ie the kernel 
>    infrastructure just doesn't do exceptions for C++, nor will it run any 
>    static constructors etc).

So what actually can be made useable (and what actually makes sense):

  * Classes with public and private funct^Wmembers, constructors.
  * Namespaces? Don't think they're all _that_ useful for us.
  * Static constructors probably won't fly.

> Anyway, it should all be doable. Not necessarily even very hard. But I 
> doubt it's worth it.

I guess if somebody has a large portion of well-separated C++ code
(eg. a complete and complex filesystem), it would be easier to write
some glue code to "run" the C++ code with the kernel.

Though it would be even easier to use FUSE's bindings:-)

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 für einen Freien Staat voll Freier Bürger"  | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-26 20:09                       ` Linus Torvalds
  2006-04-26 20:19                         ` Al Viro
  2006-04-26 20:25                         ` Jan-Benedict Glaw
@ 2006-04-26 20:43                         ` David Schwartz
  2006-04-26 23:00                         ` Roman Kononov
  3 siblings, 0 replies; 200+ messages in thread
From: David Schwartz @ 2006-04-26 20:43 UTC (permalink / raw)
  To: torvalds, Jan-Benedict Glaw; +Cc: linux-kernel


Linus wrote:

> On Wed, 26 Apr 2006, Jan-Benedict Glaw wrote:

> > There's one _practical_ thing you need to keep in mind: you'll either
> > need 'C++'-clean kernel headers (to interface low-level kernel
> > functions) or a separate set of headers.

> I suspect it would be easier to just do
>
> 	extern "C" {
> 	#include <linux/xyz.h>
> 	...
> 	}

> instead of having anything really C++'aware in the headers.

	I agree. This could include things like:

#define class class_

	You'd need two includes, one that goes first and one that goes last (to
undefine these things). Yeah, it's ugly, but it imposes the minimum cost on
those who don't care.

> If by "clean" you meant that the above works, then yeah, there might be
> _some_ cases where we use C++ keywords etc in the headers, but
> they should
> be pretty unusual and easy to fix.

	They can be fixed ugly ways or nice ways, depending on a cost/benefit
analysis.

> The real problem with C++ for kernel modules is:
>
>  - the language just sucks. Sorry, but it does.
>  - some of the C features we use may or may not be usable from C++
>    (statement expressions?)
>  - the compilers are slower, and less reliable. This is _less_ of
> an issue
>    these days than it used to be (at least the reliability part),
> but it's
>    still true.
>  - a lot of the C++ features just won't be supported sanely (ie
> the kernel
>    infrastructure just doesn't do exceptions for C++, nor will it run any
>    static constructors etc).

	I would phrase the argument as such: any project that can really benefit
from what C++ adds to C is probably too big and complex to belong in the
kernel. Better to do what you need to get it out of the kernel.

	A better project might be some compromise between kernel space and user
space that doesn't abuse the kernel stack and where things like exceptions
can be supported.

> Anyway, it should all be doable. Not necessarily even very hard. But I
> doubt it's worth it.

	If FUSE made it so that you could just as well put a filesystem in user
space as kernel space, I'd agree with you. File systems are the only kernel
drivers I can think of that can justify sufficient complexity to get much
benefit from C++. This may change though, and this could just be a lack of
imagination on my part.

	By the way, I am not a proponent of C++ in the kernel or of making changes
to the kernel to support C++. I'm just someone who labels bullshit as such
when he sees it.

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 20:09                     ` Xavier Bestel
@ 2006-04-26 20:44                       ` Randy.Dunlap
  2006-05-02 20:09                         ` C++ pushback + sparse Randy.Dunlap
  2006-04-27  7:49                       ` C++ pushback Jiri Kosina
  1 sibling, 1 reply; 200+ messages in thread
From: Randy.Dunlap @ 2006-04-26 20:44 UTC (permalink / raw)
  To: Xavier Bestel; +Cc: davids, linux-kernel

On Wed, 26 Apr 2006 22:09:51 +0200 Xavier Bestel wrote:

> Le mercredi 26 avril 2006 à 12:25 -0700, David Schwartz a écrit :
> 
> > 	C++ has how many additional reserved words? I believe the list is delete,
> > friend, private, protected, public, template, throw, try, and catch.
> 
> You forgot namespace, mutable, new, class, const_cast, dynamic_cast,
> static_cast, reinterpret_cast, explicit, true, false, operator, typeid,
> typename and virtual. Maybe I forgot some (interface ?). Probably some
> new ones will appear.

I did a sparse patch to check for all(?) of those once (with Linus's
help).  I don't know if it still applies or not...

It's at http://www.xenotime.net/linux/sparse/check_keywords_v7.patch
(You'll also need the other patch there; they got a bit comingled:
http://www.xenotime.net/linux/sparse/check_sizeof_v7.patch)

---
~Randy

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 19:25                   ` David Schwartz
                                       ` (2 preceding siblings ...)
  2006-04-26 20:09                     ` Xavier Bestel
@ 2006-04-26 21:05                     ` Martin Mares
  3 siblings, 0 replies; 200+ messages in thread
From: Martin Mares @ 2006-04-26 21:05 UTC (permalink / raw)
  To: David Schwartz; +Cc: linux-kernel

> 	C++ has how many additional reserved words? I believe the list is delete,
> friend, private, protected, public, template, throw, try, and catch.
> Renaming every symbol that currently has a name from this list to the
> corresponding name with a trailing underscore is an easily understood
> consistent change.

... which, for the point of view of people developing most parts of the
kernel (and thus not caring about C++ much) just makes the names ugly.
When some struct member describes a device class the device belongs to,
calling it anything else than "class" is silly.

But yes, the C++ modules can redefine such things by macros when
including kernel headers.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Linux vs. Windows is a no-WIN situation.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 20:19                         ` Al Viro
@ 2006-04-26 21:37                           ` Sam Ravnborg
  2006-04-28  9:23                             ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Sam Ravnborg @ 2006-04-26 21:37 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, Jan-Benedict Glaw, linux-kernel, David Schwartz

On Wed, Apr 26, 2006 at 09:19:09PM +0100, Al Viro wrote:
> On Wed, Apr 26, 2006 at 01:09:38PM -0700, Linus Torvalds wrote:
> > The real problem with C++ for kernel modules is:
> > 
> >  - the language just sucks. Sorry, but it does.
> >  - some of the C features we use may or may not be usable from C++ 
> >    (statement expressions?)
> >  - the compilers are slower, and less reliable. This is _less_ of an issue 
> >    these days than it used to be (at least the reliability part), but it's 
> >    still true.
> >  - a lot of the C++ features just won't be supported sanely (ie the kernel 
> >    infrastructure just doesn't do exceptions for C++, nor will it run any 
> >    static constructors etc).
> 
>    - a lot of C++ advocates agree that some subset could be used sanely,
>      but there's no agreement as to _which_ subset would that be.
The original question was related to port existing C++ code to be used
as a kernel module.
Magically this always ends up in long discussions about how applicable
C++ is the the kernel as such which was not the original intent.

So following the original intent it does not matter what subset is
sanely used, only what adaptions is needed to kernel proper to support
modules written in C++.

But I have seen no patches this time either, so required modifications
are yet to be identified.

	Sam

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 20:09                       ` Linus Torvalds
                                           ` (2 preceding siblings ...)
  2006-04-26 20:43                         ` David Schwartz
@ 2006-04-26 23:00                         ` Roman Kononov
  2006-04-27  0:38                           ` Kyle Moffett
                                             ` (4 more replies)
  3 siblings, 5 replies; 200+ messages in thread
From: Roman Kononov @ 2006-04-26 23:00 UTC (permalink / raw)
  To: linux-kernel

Linus Torvalds wrote:
> 
> On Wed, 26 Apr 2006, Jan-Benedict Glaw wrote:
>> There's one _practical_ thing you need to keep in mind: you'll either
>> need 'C++'-clean kernel headers (to interface low-level kernel
>> functions) or a separate set of headers.
> 
> I suspect it would be easier to just do
> 
> 	extern "C" {
> 	#include <linux/xyz.h>
> 	...
> 	}
> 
> instead of having anything really C++'aware in the headers.
> 
> If by "clean" you meant that the above works, then yeah, there might be 
> _some_ cases where we use C++ keywords etc in the headers, but they should 
> be pretty unusual and easy to fix.
> 
> The real problem with C++ for kernel modules is:
> 
>  - the language just sucks. Sorry, but it does.
Sorry, you do not know the language, and your statement is not 
credible. I think that C sucks.

>  - some of the C features we use may or may not be usable from C++ 
>    (statement expressions?)
Statement expressions are working fine in g++. The main difficulties are:
    - GCC's structure member initialization extensions are syntax
      errors in G++: struct foo_t foo={.member=0};
    - empty structures are not zero-sized in g++, unless they are like
      this one: struct really_empty_t { char dummy[0]; };

>  - the compilers are slower, and less reliable. This is _less_ of an issue 
>    these days than it used to be (at least the reliability part), but it's 
>    still true.
G++ compiling heavy C++ is a bit slower than gcc. The g++ front end is 
reliable enough. Do you have a particular bug in mind?

>  - a lot of the C++ features just won't be supported sanely (ie the kernel 
>    infrastructure just doesn't do exceptions for C++, nor will it run any 
>    static constructors etc).
A lot of C++ features are already supported sanely. You simply need to 
understand them. Especially templates and type checking. C++ 
exceptions are not very useful tool in kernels. Static constructor 
issue is trivial. I use all C++ features (except exceptions) in all 
projects: Linux kernel modules, embedded real-time applications, 
everywhere. They _really_ help a lot.

>
> Anyway, it should all be doable. Not necessarily even very hard. But I 
> doubt it's worth it.
> 
> 		Linus

I think that allowing C++ code to co-exist with the kernel would be a 
step forward.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 23:00                         ` Roman Kononov
@ 2006-04-27  0:38                           ` Kyle Moffett
  2006-04-27  2:05                             ` Roman Kononov
  2006-04-27  3:57                           ` Willy Tarreau
                                             ` (3 subsequent siblings)
  4 siblings, 1 reply; 200+ messages in thread
From: Kyle Moffett @ 2006-04-27  0:38 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel

On Apr 26, 2006, at 19:00:52, Roman Kononov wrote:
> Linus Torvalds wrote:
>>  - some of the C features we use may or may not be usable from C+ 
>> +    (statement expressions?)
>
> Statement expressions are working fine in g++. The main  
> difficulties are:
>    - GCC's structure member initialization extensions are syntax
>      errors in G++: struct foo_t foo={.member=0};

And that breaks a _massive_ amount of kernel code, including such  
core functionality like SPIN_LOCK_UNLOCKED and a host of others.   
There are all sorts of macros that use member initialization of that  
form.


>    - empty structures are not zero-sized in g++, unless they are like
>      this one: struct really_empty_t { char dummy[0]; };

And that provides yet more ways to break binary compatibility.  Not  
to mention the fact that it appears to change other aspects of the  
way structs are packed.  Since the kernel uses a lot of data  
structures to strictly define binary formats for transmission to  
hardware, across a network, or to userspace, such changes can cause  
nothing but heartache.


>>  - the compilers are slower, and less reliable. This is _less_ of  
>> an issue    these days than it used to be (at least the  
>> reliability part), but it's still true.
>
> G++ compiling heavy C++ is a bit slower than gcc. The g++ front end  
> is reliable enough. Do you have a particular bug in mind?

A lot of people would consider the "significantly slower" to be a  
major bug.  Many people moaned when the kernel stopped supporting GCC  
2.x because that compiler was much faster than modern C compilers.   
I've seen up to a 3x slowdown when compiling the same files with g++  
instead of gcc, and such would be unacceptable to a _lot_ of people  
on this list.


>>  - a lot of the C++ features just won't be supported sanely (ie  
>> the kernel    infrastructure just doesn't do exceptions for C++,  
>> nor will it run any    static constructors etc).
>
> A lot of C++ features are already supported sanely. You simply need  
> to understand them. Especially templates and type checking.

First of all, the only way to sanely use templated classes is to  
write them completely inline, which causes massive bloat.  Look at  
the kernel "struct list_head" and show me the "type-safe C++" way to  
do that.  It uses a templated inline class, right?  That templated  
inline class gets duplicated for each different type of object put in  
a linked list, no?  Think about how many linked lists we have in the  
kernel and tell me why that would be a good thing.


> Static constructor issue is trivial.

How so?  When do you want the static constructors to be run?  There  
are many different major stages of kernel-level initialization;  
picking one is likely to make them useless for other code.

Cheers,
Kyle Moffett


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  0:38                           ` Kyle Moffett
@ 2006-04-27  2:05                             ` Roman Kononov
  2006-04-27  3:37                               ` Kyle Moffett
  2006-04-27  8:50                               ` Martin Mares
  0 siblings, 2 replies; 200+ messages in thread
From: Roman Kononov @ 2006-04-27  2:05 UTC (permalink / raw)
  To: linux-kernel

Kyle Moffett wrote:
> On Apr 26, 2006, at 19:00:52, Roman Kononov wrote:
>> Linus Torvalds wrote:
>>>  - some of the C features we use may or may not be usable from C++    
>>> (statement expressions?)
>>
>> Statement expressions are working fine in g++. The main difficulties are:
>>    - GCC's structure member initialization extensions are syntax
>>      errors in G++: struct foo_t foo={.member=0};
> 
> And that breaks a _massive_ amount of kernel code, including such core 
> functionality like SPIN_LOCK_UNLOCKED and a host of others.  There are 
> all sorts of macros that use member initialization of that form.
This does not break the code at run time, this breaks the code at 
compile time, and should be less painful.

>>    - empty structures are not zero-sized in g++, unless they are like
>>      this one: struct really_empty_t { char dummy[0]; };
> 
> And that provides yet more ways to break binary compatibility.  Not to 
> mention the fact that it appears to change other aspects of the way 
> structs are packed.  Since the kernel uses a lot of data structures to 
> strictly define binary formats for transmission to hardware, across a 
> network, or to userspace, such changes can cause nothing but heartache.
This breaks the code at run time and is the _real_ pain to think 
about. As for packing for network and hardware - not an issue at all. 
The difference between gcc and g++ is _only_ in empty structures.

>>>  - the compilers are slower, and less reliable. This is _less_ of an 
>>> issue    these days than it used to be (at least the reliability 
>>> part), but it's still true.
>>
>> G++ compiling heavy C++ is a bit slower than gcc. The g++ front end is 
>> reliable enough. Do you have a particular bug in mind?
> 
> A lot of people would consider the "significantly slower" to be a major 
> bug.  Many people moaned when the kernel stopped supporting GCC 2.x 
> because that compiler was much faster than modern C compilers.  I've 
> seen up to a 3x slowdown when compiling the same files with g++ instead 
> of gcc, and such would be unacceptable to a _lot_ of people on this list.
I agree, it would be a bad idea to compile the existing C code by g++. 
  The good idea is to be able to produce new C++ modules etc.

>>>  - a lot of the C++ features just won't be supported sanely (ie the 
>>> kernel    infrastructure just doesn't do exceptions for C++, nor will 
>>> it run any    static constructors etc).
>>
>> A lot of C++ features are already supported sanely. You simply need to 
>> understand them. Especially templates and type checking.
> 
> First of all, the only way to sanely use templated classes is to write 
> them completely inline, which causes massive bloat.  Look at the kernel 
> "struct list_head" and show me the "type-safe C++" way to do that.  It 
> uses a templated inline class, right?  That templated inline class gets 
> duplicated for each different type of object put in a linked list, no?  
> Think about how many linked lists we have in the kernel and tell me why 
> that would be a good thing.
You mentioned a bad example. The struct list_head has [almost?] all 
"members" inlined. If they were not, one could simply make a base 
class having [some] members outlined, and which class does not enforce 
type safety and is for inheritance only. The template class would then 
inherit the base one enforcing type safety by having inline members. 
This technique is well known, trust me. If you need real life 
examples, tell me.

>> Static constructor issue is trivial.
> 
> How so?  When do you want the static constructors to be run?  There are 
> many different major stages of kernel-level initialization; picking one 
> is likely to make them useless for other code.
For modules there are #defines module_init() and module_exit(). These 
are the natural places for the constructors and destructors.

For #defines core_initcall() ... late_initcall() I would type 
something like this:
	class foo_t { foo_t(); ~foo_t(); }
	static char foo_storage[sizeof(foo_t)];
	static foo_t& foo=*reinterpret_cast<foo_t*>(foo_storage);
	static void __init foo_init() { new(foo_storage) foo_t; }
	core_initcall(foo_init);
This ugly-looking code can be nicely wrapped into a template, which, 
depending on the type (foo_t in this case), at compile time, picks the 
proper stage for initialization.

Regards,
Roman


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  2:05                             ` Roman Kononov
@ 2006-04-27  3:37                               ` Kyle Moffett
  2006-04-27  5:37                                 ` Roman Kononov
                                                   ` (2 more replies)
  2006-04-27  8:50                               ` Martin Mares
  1 sibling, 3 replies; 200+ messages in thread
From: Kyle Moffett @ 2006-04-27  3:37 UTC (permalink / raw)
  To: Roman Kononov; +Cc: LKML Kernel

On Apr 26, 2006, at 22:05:31, Roman Kononov wrote:
> Kyle Moffett wrote:
>> On Apr 26, 2006, at 19:00:52, Roman Kononov wrote:
>>> Linus Torvalds wrote:
>>>>  - some of the C features we use may or may not be usable from C+ 
>>>> +    (statement expressions?)
>>>
>>> Statement expressions are working fine in g++. The main  
>>> difficulties are:
>>>    - GCC's structure member initialization extensions are syntax
>>>      errors in G++: struct foo_t foo={.member=0};
>>
>> And that breaks a _massive_ amount of kernel code, including such  
>> core functionality like SPIN_LOCK_UNLOCKED and a host of others.   
>> There are all sorts of macros that use member initialization of  
>> that form.
>
> This does not break the code at run time, this breaks the code at  
> compile time, and should be less painful.

So breaking 90% of the source code at compile time is ok?  I think  
not.  The kernel relies really _really_ heavily on such structure  
initializers, and breaking them would effectively break the world as  
far as the kernel is concerned.


>>> G++ compiling heavy C++ is a bit slower than gcc. The g++ front  
>>> end is reliable enough. Do you have a particular bug in mind?
>>
>> A lot of people would consider the "significantly slower" to be a  
>> major bug.  Many people moaned when the kernel stopped supporting  
>> GCC 2.x because that compiler was much faster than modern C  
>> compilers.  I've seen up to a 3x slowdown when compiling the same  
>> files with g++ instead of gcc, and such would be unacceptable to a  
>> _lot_ of people on this list.
>
> I agree, it would be a bad idea to compile the existing C code by g+ 
> +.  The good idea is to be able to produce new C++ modules etc.

No, this is a reason why C++ modules are _not_ a good idea.  If you  
could write the module in C or C++, but in C++ it compiled 100-200%  
slower, then you would write it in C.  Why?  A simple matter of numbers:

Say it takes you 100 hours to write and debug the module in C++, and  
140 to write and debug it in C.  I estimate that at least 200,000  
people would download and compile a single version of the kernel with  
your module (not an unreasonable estimate).  Note that I'm not even  
including the people who do repeated regression testing of versions,  
or people who download and compile multiple versions of the kernel.    
If the source file takes an average of 1.0 seconds to compile in C  
and 2.0 seconds to compile in C++, then:

(2.0 sec - 1.0 sec) * 200,000 = 200,000 seconds = 55.6 hours
140 hours - 100 hours = 40 hours
40 hours < 55.6 hours

So for a single version of the kernel your module, you've already  
wasted 15.6 hours of time across people using it.  Over time that  
number is just going to grow, _especially_ if people start writing  
more and more modules in C++ because they can.  If you want to build C 
++ in the kernel, write a compiler that does not include all the  
problematic C++ features that add so much parsing time (overloaded  
operators, etc).


>>> A lot of C++ features are already supported sanely. You simply  
>>> need to understand them. Especially templates and type checking.
>>
>> First of all, the only way to sanely use templated classes is to  
>> write them completely inline, which causes massive bloat.  Look at  
>> the kernel "struct list_head" and show me the "type-safe C++" way  
>> to do that.  It uses a templated inline class, right?  That  
>> templated inline class gets duplicated for each different type of  
>> object put in a linked list, no?  Think about how many linked  
>> lists we have in the kernel and tell me why that would be a good  
>> thing.
>
> You mentioned a bad example. The struct list_head has [almost?] all  
> "members" inlined. If they were not, one could simply make a base  
> class having [some] members outlined, and which class does not  
> enforce type safety and is for inheritance only.  The template  
> class would then inherit the base one enforcing type safety by  
> having inline members. This technique is well known, trust me. If  
> you need real life examples, tell me.

Ok, help me understand here:  Instead of helping using one sensible  
data structure and generating optimized code for that, the language  
actively _encourages_ you to duplicate classes and interfaces,  
providing even _more_ work for the compiler, making the code harder  
to debug, and probably introducing inefficiencies as well.  If C++  
doesn't work properly for a simple and clean example like struct  
list_head, why should we assume that it's going to work any better  
for more complicated examples in the rest of the kernel?  Whether or  
not some arbitrary function is inlined should be totally orthogonal  
to adding type-checking.

>>> Static constructor issue is trivial.
>>
>> How so?  When do you want the static constructors to be run?   
>> There are many different major stages of kernel-level  
>> initialization; picking one is likely to make them useless for  
>> other code.
>
> For #defines core_initcall() ... late_initcall() I would type  
> something like this:
> 	class foo_t { foo_t(); ~foo_t(); }
> 	static char foo_storage[sizeof(foo_t)];
> 	static foo_t& foo=*reinterpret_cast<foo_t*>(foo_storage);
> 	static void __init foo_init() { new(foo_storage) foo_t; }
> 	core_initcall(foo_init);
>
> This ugly-looking code can be nicely wrapped into a template,  
> which, depending on the type (foo_t in this case), at compile time,  
> picks the proper stage for initialization.

You proved my point.  Static constructors can't work.  You can add  
silly wrapper initcall functions which create objects in static  
memory at various times, but the language-defined static constructors  
are yet another C++ feature that doesn't work by default and has to  
be hacked around.  C++ gives us no advantage over C here either.   
Plus this would break things like static spinlock initialization.   
How would you make this work sanely for this static declaration:

spinlock_t foo_lock = SPIN_LOCK_UNLOCKED;

Under C that turns into (depending on config options):

spinlock_t foo_lock = { .value = 0, .owner = NULL, (...) };

How could that possibly work in C++ given what you've said?  Anything  
that breaks code that simple is an automatic nonstarter for the  
kernel.  Also remember that spinlocks are defined preinitialized at  
the very earliest stages of init.  Of course I probably don't have to  
say that anything that tries to run a function to iterate over all  
statically-allocated spinlocks during init would be rejected out of  
hand.

Cheers,
Kyle Moffett


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 23:00                         ` Roman Kononov
  2006-04-27  0:38                           ` Kyle Moffett
@ 2006-04-27  3:57                           ` Willy Tarreau
  2006-04-27  5:53                             ` Roman Kononov
  2006-04-27  7:55                           ` Jan-Benedict Glaw
                                             ` (2 subsequent siblings)
  4 siblings, 1 reply; 200+ messages in thread
From: Willy Tarreau @ 2006-04-27  3:57 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel, torvalds

On Wed, Apr 26, 2006 at 06:00:52PM -0500, Roman Kononov wrote:
> Linus Torvalds wrote:
> > - the compilers are slower, and less reliable. This is _less_ of an 
> > issue these days than it used to be (at least the reliability part), 
> >   but it's still true.
> G++ compiling heavy C++ is a bit slower than gcc. The g++ front end is 
> reliable enough. Do you have a particular bug in mind?

Obviously you're not interested in gcc evolutions. I suggest that you
take your browser to http://gcc.gnu.org/gcc-3.4/changes.html#3.4.5
This is the last version which showed per-subsystem problem reports
before they used SVN. Just count the lines : 9 bugs fixed for C, 45
for C++. And when you read those bugs, you don't have the feeling of
reading a description of something that people make their code rely on.

Regards,
Willy


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  3:37                               ` Kyle Moffett
@ 2006-04-27  5:37                                 ` Roman Kononov
  2006-04-27 13:58                                   ` Michael Buesch
  2006-04-27  8:07                                 ` Avi Kivity
  2006-04-27 14:50                                 ` Sam Ravnborg
  2 siblings, 1 reply; 200+ messages in thread
From: Roman Kononov @ 2006-04-27  5:37 UTC (permalink / raw)
  To: linux-kernel

Kyle Moffett wrote:
> On Apr 26, 2006, at 22:05:31, Roman Kononov wrote:
>> Kyle Moffett wrote:
>>> On Apr 26, 2006, at 19:00:52, Roman Kononov wrote:
>>>> Linus Torvalds wrote:
>>>>>  - some of the C features we use may or may not be usable from 
>>>>> C++    (statement expressions?)
>>>>
>>>> Statement expressions are working fine in g++. The main difficulties 
>>>> are:
>>>>    - GCC's structure member initialization extensions are syntax
>>>>      errors in G++: struct foo_t foo={.member=0};
>>>
>>> And that breaks a _massive_ amount of kernel code, including such 
>>> core functionality like SPIN_LOCK_UNLOCKED and a host of others.  
>>> There are all sorts of macros that use member initialization of that 
>>> form.
>>
>> This does not break the code at run time, this breaks the code at 
>> compile time, and should be less painful.
> 
> So breaking 90% of the source code at compile time is ok?  I think not.  
> The kernel relies really _really_ heavily on such structure 
> initializers, and breaking them would effectively break the world as far 
> as the kernel is concerned.

I agree: do not break code, fix it. Make it more robust language-wise.

>>>> G++ compiling heavy C++ is a bit slower than gcc. The g++ front end 
>>>> is reliable enough. Do you have a particular bug in mind?
>>>
>>> A lot of people would consider the "significantly slower" to be a 
>>> major bug.  Many people moaned when the kernel stopped supporting GCC 
>>> 2.x because that compiler was much faster than modern C compilers.  
>>> I've seen up to a 3x slowdown when compiling the same files with g++ 
>>> instead of gcc, and such would be unacceptable to a _lot_ of people 
>>> on this list.
>>
>> I agree, it would be a bad idea to compile the existing C code by 
>> g++.  The good idea is to be able to produce new C++ modules etc.
> 
> No, this is a reason why C++ modules are _not_ a good idea.  If you 
> could write the module in C or C++, but in C++ it compiled 100-200% 
> slower, then you would write it in C.  Why?  A simple matter of numbers:
> 
> Say it takes you 100 hours to write and debug the module in C++, and 140 
> to write and debug it in C.  I estimate that at least 200,000 people 
> would download and compile a single version of the kernel with your 
> module (not an unreasonable estimate).  Note that I'm not even including 
> the people who do repeated regression testing of versions, or people who 
> download and compile multiple versions of the kernel.   If the source 
> file takes an average of 1.0 seconds to compile in C and 2.0 seconds to 
> compile in C++, then:
> 
> (2.0 sec - 1.0 sec) * 200,000 = 200,000 seconds = 55.6 hours
> 140 hours - 100 hours = 40 hours
> 40 hours < 55.6 hours
> 
> So for a single version of the kernel your module, you've already wasted 
> 15.6 hours of time across people using it.  Over time that number is 
> just going to grow, _especially_ if people start writing more and more 
> modules in C++ because they can.  If you want to build C++ in the 
> kernel, write a compiler that does not include all the problematic C++ 
> features that add so much parsing time (overloaded operators, etc).

It is hard take this seriously. For people like me, it is 5 times faster 
to type and debug C++ code. And debug time is 50 times more expensive 
then compile time.

>>>> A lot of C++ features are already supported sanely. You simply need 
>>>> to understand them. Especially templates and type checking.
>>>
>>> First of all, the only way to sanely use templated classes is to 
>>> write them completely inline, which causes massive bloat.  Look at 
>>> the kernel "struct list_head" and show me the "type-safe C++" way to 
>>> do that.  It uses a templated inline class, right?  That templated 
>>> inline class gets duplicated for each different type of object put in 
>>> a linked list, no?  Think about how many linked lists we have in the 
>>> kernel and tell me why that would be a good thing.
>>
>> You mentioned a bad example. The struct list_head has [almost?] all 
>> "members" inlined. If they were not, one could simply make a base 
>> class having [some] members outlined, and which class does not enforce 
>> type safety and is for inheritance only.  The template class would 
>> then inherit the base one enforcing type safety by having inline 
>> members. This technique is well known, trust me. If you need real life 
>> examples, tell me.
> 
> Ok, help me understand here:  Instead of helping using one sensible data 
> structure and generating optimized code for that, the language actively 
> _encourages_ you to duplicate classes and interfaces, providing even 
> _more_ work for the compiler, making the code harder to debug, and 
> probably introducing inefficiencies as well.

The C++ language does not encourage anything like this. Instead it 
actively debugs my code. And it does not produce inefficiencies at run 
time unless I do something stupid.

> If C++ doesn't work 
> properly for a simple and clean example like struct list_head, why 
> should we assume that it's going to work any better for more complicated 
> examples in the rest of the kernel?  Whether or not some arbitrary 
> function is inlined should be totally orthogonal to adding type-checking.

You misunderstood something. The struct list_head is indeed a perfect 
type to be templatized with all members inlined. C++ works properly in 
this case.

>>>> Static constructor issue is trivial.
>>>
>>> How so?  When do you want the static constructors to be run?  There 
>>> are many different major stages of kernel-level initialization; 
>>> picking one is likely to make them useless for other code.
>>
>> For #defines core_initcall() ... late_initcall() I would type 
>> something like this:
>>     class foo_t { foo_t(); ~foo_t(); }
>>     static char foo_storage[sizeof(foo_t)];
>>     static foo_t& foo=*reinterpret_cast<foo_t*>(foo_storage);
>>     static void __init foo_init() { new(foo_storage) foo_t; }
>>     core_initcall(foo_init);
>>
>> This ugly-looking code can be nicely wrapped into a template, which, 
>> depending on the type (foo_t in this case), at compile time, picks the 
>> proper stage for initialization.
> 
> You proved my point.  Static constructors can't work.  You can add silly 
> wrapper initcall functions which create objects in static memory at 
> various times, but the language-defined static constructors are yet 
> another C++ feature that doesn't work by default and has to be hacked 
> around.  C++ gives us no advantage over C here either.

Nothing works by default. I did not say that static constructors are 
advantageous. I said that it is easy for the kernel to make static 
constructors working. Global variables should be deprecated anyway.

> Plus this would 
> break things like static spinlock initialization.  How would you make 
> this work sanely for this static declaration:
> 
> spinlock_t foo_lock = SPIN_LOCK_UNLOCKED;
> 
> Under C that turns into (depending on config options):
> 
> spinlock_t foo_lock = { .value = 0, .owner = NULL, (...) };

I would make it exactly like this:
	#define SPIN_LOCK_UNLOCKED (spinlock_t){0,-1,whatever}
	spinlock_t foo_lock=SPIN_LOCK_UNLOCKED;
This is easy to change. The empty structures look far more painful.

> How could that possibly work in C++ given what you've said?  Anything 
> that breaks code that simple is an automatic nonstarter for the kernel.  
> Also remember that spinlocks are defined preinitialized at the very 
> earliest stages of init.  Of course I probably don't have to say that 
> anything that tries to run a function to iterate over all 
> statically-allocated spinlocks during init would be rejected out of hand.

Apparently this would be rejected. Why would it?

Regards
Roman Kononov


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  3:57                           ` Willy Tarreau
@ 2006-04-27  5:53                             ` Roman Kononov
  0 siblings, 0 replies; 200+ messages in thread
From: Roman Kononov @ 2006-04-27  5:53 UTC (permalink / raw)
  To: linux-kernel

On 04/26/2006 22:57, Willy Tarreau wrote:
> On Wed, Apr 26, 2006 at 06:00:52PM -0500, Roman Kononov wrote:
>> Linus Torvalds wrote:
>>> - the compilers are slower, and less reliable. This is _less_ of an 
>>> issue these days than it used to be (at least the reliability part), 
>>>   but it's still true.
>> G++ compiling heavy C++ is a bit slower than gcc. The g++ front end is 
>> reliable enough. Do you have a particular bug in mind?
> 
> Obviously you're not interested in gcc evolutions. I suggest that you
> take your browser to http://gcc.gnu.org/gcc-3.4/changes.html#3.4.5
> This is the last version which showed per-subsystem problem reports
> before they used SVN. Just count the lines : 9 bugs fixed for C, 45
> for C++. And when you read those bugs, you don't have the feeling of
> reading a description of something that people make their code rely on.

I am interested very much. And if one really understands the bugs 
listed, he can say that they are minor for both C and C++. I would 
certainly recommend rely on g++.

Regards,
Roman


^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-26 20:09                     ` Xavier Bestel
  2006-04-26 20:44                       ` Randy.Dunlap
@ 2006-04-27  7:49                       ` Jiri Kosina
  1 sibling, 0 replies; 200+ messages in thread
From: Jiri Kosina @ 2006-04-27  7:49 UTC (permalink / raw)
  To: Xavier Bestel; +Cc: davids, linux-kernel

On Wed, 26 Apr 2006, Xavier Bestel wrote:

> > 	C++ has how many additional reserved words? I believe the list is
> > delete, friend, private, protected, public, template, throw, try, and
> > catch.
> You forgot namespace, mutable, new, class, const_cast, dynamic_cast,
> static_cast, reinterpret_cast, explicit, true, false, operator, typeid,
> typename and virtual. Maybe I forgot some (interface ?). Probably some
> new ones will appear.

Please also don't forget that C is not a proper subset of C++ (i.e. the 
kernel might not be compilable by C++ compiler at all), so just renaming 
the variables which have names clashing with C++ reserved words might not 
be enough.

-- 
JiKos.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 23:00                         ` Roman Kononov
  2006-04-27  0:38                           ` Kyle Moffett
  2006-04-27  3:57                           ` Willy Tarreau
@ 2006-04-27  7:55                           ` Jan-Benedict Glaw
  2006-04-27 17:20                           ` C++ pushback (when does this religious thread end?) Leonard Peterson
  2006-04-30 17:48                           ` C++ pushback Jan Harkes
  4 siblings, 0 replies; 200+ messages in thread
From: Jan-Benedict Glaw @ 2006-04-27  7:55 UTC (permalink / raw)
  To: linux-kernel; +Cc: Roman Kononov

[-- Attachment #1: Type: text/plain, Size: 1551 bytes --]

On Wed, 2006-04-26 18:00:52 -0500, Roman Kononov <kononov195-far@yahoo.com> wrote:
> Statement expressions are working fine in g++. The main difficulties are:
>    - GCC's structure member initialization extensions are syntax
>      errors in G++: struct foo_t foo={.member=0};

Erm, you may want to read the current C standard (C99). This isn't an
extension, it's standard.

There's a reason why C++ doesn't support that (yet): C++ is a fork of
C90 (IIRC), so everything that evolved in C during the years is still
missing from C++.

> > Anyway, it should all be doable. Not necessarily even very hard. But I 
> > doubt it's worth it.
> 
> I think that allowing C++ code to co-exist with the kernel would be a 
> step forward.

You can do with your code whatever you want to:)  I think it's just a
matter of practice: If C++ code shows up that is less error-prone than
C code, doesn't use unverifyable amounts of stack space during
constructor runs and is basically _superior_ to C code, that'll find
its way into the kernel. But if it's only as good as the C code, then
why should anybody bother implementing the neccessary stuff to link
C++ code (and to initialize it properly?)

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 für einen Freien Staat voll Freier Bürger"  | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  3:37                               ` Kyle Moffett
  2006-04-27  5:37                                 ` Roman Kononov
@ 2006-04-27  8:07                                 ` Avi Kivity
  2006-04-27 13:55                                   ` Denis Vlasenko
  2006-04-27 14:50                                 ` Sam Ravnborg
  2 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-27  8:07 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Roman Kononov, LKML Kernel

Kyle Moffett wrote:
>>>
>>> And that breaks a _massive_ amount of kernel code, including such 
>>> core functionality like SPIN_LOCK_UNLOCKED and a host of others.  
>>> There are all sorts of macros that use member initialization of that 
>>> form.
>>
>> This does not break the code at run time, this breaks the code at 
>> compile time, and should be less painful.
>
> So breaking 90% of the source code at compile time is ok?  I think 
> not.  The kernel relies really _really_ heavily on such structure 
> initializers, and breaking them would effectively break the world as 
> far as the kernel is concerned.
>

Since we're now discussing how to effectively port the kernel to C++, 
I'd suggest getting g++ to accept these structure initializers, and move 
them incrementally to standard C++ code.

Should be similar to the conversion to C99 initializers.

>>
>> I agree, it would be a bad idea to compile the existing C code by 
>> g++.  The good idea is to be able to produce new C++ modules etc.
>
> No, this is a reason why C++ modules are _not_ a good idea.  If you 
> could write the module in C or C++, but in C++ it compiled 100-200% 
> slower, then you would write it in C.  Why?  A simple matter of numbers:
>
> Say it takes you 100 hours to write and debug the module in C++, and 
> 140 to write and debug it in C.  I estimate that at least 200,000 
> people would download and compile a single version of the kernel with 
> your module (not an unreasonable estimate).  Note that I'm not even 
> including the people who do repeated regression testing of versions, 
> or people who download and compile multiple versions of the kernel.   
> If the source file takes an average of 1.0 seconds to compile in C and 
> 2.0 seconds to compile in C++, then:
>
> (2.0 sec - 1.0 sec) * 200,000 = 200,000 seconds = 55.6 hours
> 140 hours - 100 hours = 40 hours
> 40 hours < 55.6 hours
>
> So for a single version of the kernel your module, you've already 
> wasted 15.6 hours of time across people using it.  Over time that 
> number is just going to grow, _especially_ if people start writing 
> more and more modules in C++ because they can.  If you want to build 
> C++ in the kernel, write a compiler that does not include all the 
> problematic C++ features that add so much parsing time (overloaded 
> operators, etc).
>
>

It looks like you don't value your time much. You're comparing human 
time (yours!) to machine time.

If we accept your 1.4 C++ vs C factor, then these 200,000 people would 
be compiling 2.6.24 instead of 2.6.16.12.

(Of course, not all code benefits equally from C++. I'd guess the VM 
internals wouldn't benefit as much, filesystems and drivers benefiting a 
lot).

C++ compilation isn't slower because the compiler has to recognize more 
keywords. It's slower because it is doing more for you: checking types 
(C++ code is usually free of void *'s except for raw data) and expanding 
those 4-line function to their 14-line goto-heavy equivalents.


>>
>> You mentioned a bad example. The struct list_head has [almost?] all 
>> "members" inlined. If they were not, one could simply make a base 
>> class having [some] members outlined, and which class does not 
>> enforce type safety and is for inheritance only.  The template class 
>> would then inherit the base one enforcing type safety by having 
>> inline members. This technique is well known, trust me. If you need 
>> real life examples, tell me.
>
> Ok, help me understand here:  Instead of helping using one sensible 
> data structure and generating optimized code for that, the language 
> actively _encourages_ you to duplicate classes and interfaces, 
> providing even _more_ work for the compiler, making the code harder to 
> debug, and probably introducing inefficiencies as well.  If C++ 
> doesn't work properly for a simple and clean example like struct 
> list_head, why should we assume that it's going to work any better for 
> more complicated examples in the rest of the kernel?  Whether or not 
> some arbitrary function is inlined should be totally orthogonal to 
> adding type-checking.

C++ works excellently for things like list_head. The generated code is 
as efficient or better that the C equivalent, and the API is *much* 
cleaner. You can iterate over a list without knowing the name of the 
field which contains your list_head (and possibly getting it wrong if 
there is more than one).


>>
>> For #defines core_initcall() ... late_initcall() I would type 
>> something like this:
>>     class foo_t { foo_t(); ~foo_t(); }
>>     static char foo_storage[sizeof(foo_t)];
>>     static foo_t& foo=*reinterpret_cast<foo_t*>(foo_storage);
>>     static void __init foo_init() { new(foo_storage) foo_t; }
>>     core_initcall(foo_init);
>>
>> This ugly-looking code can be nicely wrapped into a template, which, 
>> depending on the type (foo_t in this case), at compile time, picks 
>> the proper stage for initialization.
>
> You proved my point.  Static constructors can't work.  You can add 
> silly wrapper initcall functions which create objects in static memory 
> at various times, but the language-defined static constructors are yet 
> another C++ feature that doesn't work by default and has to be hacked 
> around.  C++ gives us no advantage over C here either.  Plus this 
> would break things like static spinlock initialization.  How would you 
> make this work sanely for this static declaration:
>
> spinlock_t foo_lock = SPIN_LOCK_UNLOCKED;
>
> Under C that turns into (depending on config options):
>
> spinlock_t foo_lock = { .value = 0, .owner = NULL, (...) };
>
> How could that possibly work in C++ given what you've said?  Anything 
> that breaks code that simple is an automatic nonstarter for the 
> kernel.  Also remember that spinlocks are defined preinitialized at 
> the very earliest stages of init.  Of course I probably don't have to 
> say that anything that tries to run a function to iterate over all 
> statically-allocated spinlocks during init would be rejected out of hand.
>

Why would it be rejected?

A static constructor is just like a module init function. Why are 
modules not rejected out of hand?


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  2:05                             ` Roman Kononov
  2006-04-27  3:37                               ` Kyle Moffett
@ 2006-04-27  8:50                               ` Martin Mares
  1 sibling, 0 replies; 200+ messages in thread
From: Martin Mares @ 2006-04-27  8:50 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel

> I agree, it would be a bad idea to compile the existing C code by g++. 
> The good idea is to be able to produce new C++ modules etc.

For which you need to compile the existing headers correctly.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
A computer without Windows is like a chocolate cake without mustard.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 22:16           ` J.A. Magallon
                               ` (4 preceding siblings ...)
  2006-04-25 18:02             ` Geert Uytterhoeven
@ 2006-04-27  9:09             ` Alexander E. Patrakov
  5 siblings, 0 replies; 200+ messages in thread
From: Alexander E. Patrakov @ 2006-04-27  9:09 UTC (permalink / raw)
  To: linux-kernel

J.A. Magallon wrote:
> Tell me what is the difference between:
> 
> 
>     sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
>     if (!sbi)
>         return -ENOMEM;
>     sb->s_fs_info = sbi;
>     memset(sbi, 0, sizeof(*sbi));
>     sbi->s_mount_opt = 0;
>     sbi->s_resuid = EXT3_DEF_RESUID;
>     sbi->s_resgid = EXT3_DEF_RESGID;
> 
> and
> 
>     SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>     {}
> 
>     ...
>     sbi = new SuperBlock;
>     if (!sbi)
>         return -ENOMEM;
> 
> apart that you don't get members initalized twice and get a shorter code :).

The second example is simply incorrect, because the operator new throws an 
exception when we run out of memory, instead of returning a null pointer.

So it has to be written as:

sbi = new SuperBlock;
/* The rest of code assumes that the sbi pointer is valid. If this was not the 
case, let's hope that the caller caught std::bad_alloc properly */

-- 
Alexander E. Patrakov


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  8:07                                 ` Avi Kivity
@ 2006-04-27 13:55                                   ` Denis Vlasenko
  2006-04-27 14:27                                     ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Denis Vlasenko @ 2006-04-27 13:55 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Roman Kononov, LKML Kernel

On Thursday 27 April 2006 11:07, Avi Kivity wrote:
> C++ compilation isn't slower because the compiler has to recognize more 
> keywords. It's slower because it is doing more for you: checking types 
> (C++ code is usually free of void *'s except for raw data) and expanding 

Today's C is much better at typechecking than ancient K&R C.

> those 4-line function to their 14-line goto-heavy equivalents.

Where do you see goto-heavy code in kernel?

> > Ok, help me understand here:  Instead of helping using one sensible 
> > data structure and generating optimized code for that, the language 
> > actively _encourages_ you to duplicate classes and interfaces, 
> > providing even _more_ work for the compiler, making the code harder to 
> > debug, and probably introducing inefficiencies as well.  If C++ 
> > doesn't work properly for a simple and clean example like struct 
> > list_head, why should we assume that it's going to work any better for 
> > more complicated examples in the rest of the kernel?  Whether or not 
> > some arbitrary function is inlined should be totally orthogonal to 
> > adding type-checking.
> 
> C++ works excellently for things like list_head. The generated code is 
> as efficient or better that the C equivalent,

"or better" part is pure BS, because there is no magic C++ compiler
can possibly do which is not implementable in C.

"as efficient", hmmm, let me see... gcc 3.4.3, presumably an contemporary
C++ compiler, i.e. which is "rather good".

Random example. gcc-3.4.3/include/g++-v3/bitset:

  template<size_t _Nw>
    struct _Base_bitset
    {
      typedef unsigned long _WordT;

      /// 0 is the least significant word.
      _WordT            _M_w[_Nw];

      _Base_bitset() { _M_do_reset(); }
...
      void
      _M_do_set()
      {
        for (size_t __i = 0; __i < _Nw; __i++)
          _M_w[__i] = ~static_cast<_WordT>(0);
      }
      void
      _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); }
...

A global or static variable of _Base_bitset or derived type
would need an init function?! Why not just preset sequence of
zeroes in data section?
[this disproves that C++ is very efficient]

Why _M_do_set() doesn't use memset()?
Why _M_do_reset() is not inlined?
[this disproves that today's C++ libs are well-written]?

> and the API is *much*  
> cleaner. You can iterate over a list without knowing the name of the 
> field which contains your list_head (and possibly getting it wrong if 
> there is more than one).

But kernel folks tend to *want to know* everything, including
names of the fields.

> > How could that possibly work in C++ given what you've said?  Anything 
> > that breaks code that simple is an automatic nonstarter for the 
> > kernel.  Also remember that spinlocks are defined preinitialized at 
> > the very earliest stages of init.  Of course I probably don't have to 
> > say that anything that tries to run a function to iterate over all 
> > statically-allocated spinlocks during init would be rejected out of hand.
> 
> Why would it be rejected?
> 
> A static constructor is just like a module init function. Why are 
> modules not rejected out of hand?

Because we do not like init functions which can be eliminated.
That's bloat.
--
vda

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  5:37                                 ` Roman Kononov
@ 2006-04-27 13:58                                   ` Michael Buesch
  2006-04-27 14:22                                     ` linux-os (Dick Johnson)
  0 siblings, 1 reply; 200+ messages in thread
From: Michael Buesch @ 2006-04-27 13:58 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1992 bytes --]

On Thursday 27 April 2006 07:37, you wrote:
> > If C++ doesn't work 
> > properly for a simple and clean example like struct list_head, why 
> > should we assume that it's going to work any better for more complicated 
> > examples in the rest of the kernel?  Whether or not some arbitrary 
> > function is inlined should be totally orthogonal to adding type-checking.
> 
> You misunderstood something. The struct list_head is indeed a perfect 
> type to be templatized with all members inlined. C++ works properly in 
> this case.

I am not sure, if you can relieably use the container_of() magic
in C++. Do you know?
I have a C++ linked list example here:
http://websvn.kde.org/trunk/extragear/security/pwmanager/pwmanager/libpwmanager/linkedlist.h?rev=421676&view=markup
It is very simple and in some points different from the kernel
linked lists. It has a separate "head" and "entry" class and it stores
a pointer to the entry (the kernel linked lists would use container_of()
instead)

> Nothing works by default. I did not say that static constructors are 
> advantageous. I said that it is easy for the kernel to make static 
> constructors working. Global variables should be deprecated anyway.

You are kidding. Must be...

> > Plus this would 
> > break things like static spinlock initialization.  How would you make 
> > this work sanely for this static declaration:
> > 
> > spinlock_t foo_lock = SPIN_LOCK_UNLOCKED;
> > 
> > Under C that turns into (depending on config options):
> > 
> > spinlock_t foo_lock = { .value = 0, .owner = NULL, (...) };
> 
> I would make it exactly like this:
> 	#define SPIN_LOCK_UNLOCKED (spinlock_t){0,-1,whatever}
> 	spinlock_t foo_lock=SPIN_LOCK_UNLOCKED;
> This is easy to change. The empty structures look far more painful.

The lack of named initializers is one of the main reasons (for me)
why C++ damn sucks. Hopefully they will include them in the
next C++ standard.

-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 13:58                                   ` Michael Buesch
@ 2006-04-27 14:22                                     ` linux-os (Dick Johnson)
  0 siblings, 0 replies; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-27 14:22 UTC (permalink / raw)
  To: Michael Buesch; +Cc: Roman Kononov, linux-kernel


On Thu, 27 Apr 2006, Michael Buesch wrote:

> On Thursday 27 April 2006 07:37, you wrote:
>>> If C++ doesn't work
>>> properly for a simple and clean example like struct list_head, why
>>> should we assume that it's going to work any better for more complicated
>>> examples in the rest of the kernel?  Whether or not some arbitrary
>>> function is inlined should be totally orthogonal to adding type-checking.
>>
>> You misunderstood something. The struct list_head is indeed a perfect
>> type to be templatized with all members inlined. C++ works properly in
>> this case.
>
> I am not sure, if you can relieably use the container_of() magic
> in C++. Do you know?
> I have a C++ linked list example here:
> http://websvn.kde.org/trunk/extragear/security/pwmanager/pwmanager/libpwmanager/linkedlist.h?rev=421676&view=markup
> It is very simple and in some points different from the kernel
> linked lists. It has a separate "head" and "entry" class and it stores
> a pointer to the entry (the kernel linked lists would use container_of()
> instead)
>
>> Nothing works by default. I did not say that static constructors are
>> advantageous. I said that it is easy for the kernel to make static
>> constructors working. Global variables should be deprecated anyway.
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Any operating system kernel needs globals.

1	CPUs require structures existing in physical memory. Such
structures are page-tables, interrupt descriptor tables, and global
descriptor tables.

2	The first element (at least) of a linked-list, accessed by
more than one task needs a global anchor-point.

3	The first element (at least) of an interrupt dispatch table
needs to be global. More efficient code makes the whole table
global for efficient indexing.

4	The first element (at least) of a kernel function request
dispatch table needs to be global. More efficient code makes the
whole table global.

5	Hardware, a.k.a., PCI bus access is global. There is no
way around that. If the operating system interfaces with hardware,
it interfaces with global objects. They might be artifically
"private", but still global.

6	Spin-lock and semaphore variables need to be global, existing
in non-paged memory. Again, they might be artifically "private", but
are still global.

This is just a handful of examples. If you are going to use a tool
to make an O.S., you need to use the correct tool(s).

> You are kidding. Must be...
>
[SNIPPED Rest...]


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
New book: http://www.lymanschool.com
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 13:55                                   ` Denis Vlasenko
@ 2006-04-27 14:27                                     ` Avi Kivity
  2006-04-27 14:56                                       ` Denis Vlasenko
                                                         ` (2 more replies)
  0 siblings, 3 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-27 14:27 UTC (permalink / raw)
  To: Denis Vlasenko; +Cc: Kyle Moffett, Roman Kononov, LKML Kernel

Denis Vlasenko wrote:
> On Thursday 27 April 2006 11:07, Avi Kivity wrote:
>   
>> C++ compilation isn't slower because the compiler has to recognize more 
>> keywords. It's slower because it is doing more for you: checking types 
>> (C++ code is usually free of void *'s except for raw data) and expanding 
>>     
> Today's C is much better at typechecking than ancient K&R C.
>   

It still can't typecheck void pointers. With C++ they're very rare.

Look at the contortions needed to get the min() macro to be typesafe.

>> those 4-line function to their 14-line goto-heavy equivalents.
>>     
>
> Where do you see goto-heavy code in kernel?
>
>   

[avi@cleopatra linux]$ grep -rw goto . | wc -l
37448

Repeat without 'wc' to get a detailed listing.

>> C++ works excellently for things like list_head. The generated code is 
>> as efficient or better that the C equivalent,
>>     
>
> "or better" part is pure BS, because there is no magic C++ compiler
> can possibly do which is not implementable in C.
>
>   

For list_head, no. But coding more complex data structures as type-safe 
macros is not practicable.

As an example, you can easily get C++ to inline the hash function in a 
generic hashtable or the compare in a sort. I dare you to do it in C.

> "as efficient", hmmm, let me see... gcc 3.4.3, presumably an contemporary
> C++ compiler, i.e. which is "rather good".
>   

4.1.0 is the latest.

> Random example. gcc-3.4.3/include/g++-v3/bitset:
>   

You're looking at a library while we were talking about the language and 
compiler. But anyway.

>   template<size_t _Nw>
>     struct _Base_bitset
>     {
>       typedef unsigned long _WordT;
>
>       /// 0 is the least significant word.
>       _WordT            _M_w[_Nw];
>
>       _Base_bitset() { _M_do_reset(); }
> ...
>       void
>       _M_do_set()
>       {
>         for (size_t __i = 0; __i < _Nw; __i++)
>           _M_w[__i] = ~static_cast<_WordT>(0);
>       }
>       void
>       _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); }
> ...
>
> A global or static variable of _Base_bitset or derived type
> would need an init function?! Why not just preset sequence of
> zeroes in data section?
>   

I wouldn't count startup time as efficiency, unless you have several 
million global bitset objects.

> [this disproves that C++ is very efficient]
>   

Add a constructor which does not touch the data members, and the data 
will (probably) end up in .bss.

> Why _M_do_set() doesn't use memset()?
>   

Patches accepted :)

It's just a library, you're free to optimize it. I'd guess that 
_M_do_set() is very rarely called, and that the performance difference 
is small anyway.

> Why _M_do_reset() is not inlined?
>   

It is inlined. Why do you think it is not?

> [this disproves that today's C++ libs are well-written]?
>
>   

Certainly, one can't claim that all C++ libraries are will written. But 
gcc library mostly is.

Again, if you don't like some library, don't use it. The kernel would 
use its own version anyway since it has to be freestanding.

>> and the API is *much*  
>> cleaner. You can iterate over a list without knowing the name of the 
>> field which contains your list_head (and possibly getting it wrong if 
>> there is more than one).
>>     
>
> But kernel folks tend to *want to know* everything, including
> names of the fields.
>   

The names of the fields are not hidden. You just don't have to 
mindlessly repeat them.

The 'know everything' argument seems to apply equally well to ordinary 
functions: "I *must know* about calls to schedule() and those expensive 
atomic operations, don't hide them behind mutex_lock()!"

>>> How could that possibly work in C++ given what you've said?  Anything 
>>> that breaks code that simple is an automatic nonstarter for the 
>>> kernel.  Also remember that spinlocks are defined preinitialized at 
>>> the very earliest stages of init.  Of course I probably don't have to 
>>> say that anything that tries to run a function to iterate over all 
>>> statically-allocated spinlocks during init would be rejected out of hand.
>>>       
>> Why would it be rejected?
>>
>> A static constructor is just like a module init function. Why are 
>> modules not rejected out of hand?
>>     
>
> Because we do not like init functions which can be eliminated.
> That's bloat.

I'm sure you can eliminate them if you want, but working to remove some 
microseconds of boot time is a complete waste of effort IMO.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27  3:37                               ` Kyle Moffett
  2006-04-27  5:37                                 ` Roman Kononov
  2006-04-27  8:07                                 ` Avi Kivity
@ 2006-04-27 14:50                                 ` Sam Ravnborg
  2 siblings, 0 replies; 200+ messages in thread
From: Sam Ravnborg @ 2006-04-27 14:50 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Roman Kononov, LKML Kernel

On Wed, Apr 26, 2006 at 11:37:05PM -0400, Kyle Moffett wrote:
> >
> >I agree, it would be a bad idea to compile the existing C code by g+ 
> >+.  The good idea is to be able to produce new C++ modules etc.
> 
> No, this is a reason why C++ modules are _not_ a good idea.  If you  
> could write the module in C or C++, but in C++ it compiled 100-200%  
> slower, then you would write it in C.
The original issue was the possibility to add support for C++
solely to support an existing implementation of a filesystem.
Not to rewrite the kernel in C++, neither to encourage the use of C++.
And with this in mind the figures above does not matter.

Likewise does neiter of the many arguments in this thread.
Now if the C++ fans could present what is needed to actually support
building a module in C++ instead of arguing.....

	Sam

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 14:27                                     ` Avi Kivity
@ 2006-04-27 14:56                                       ` Denis Vlasenko
  2006-04-27 15:54                                         ` Bob Copeland
  2006-04-27 16:03                                         ` Avi Kivity
  2006-04-27 15:00                                       ` Martin Mares
  2006-04-28 15:51                                       ` Jan Engelhardt
  2 siblings, 2 replies; 200+ messages in thread
From: Denis Vlasenko @ 2006-04-27 14:56 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Kyle Moffett, Roman Kononov, LKML Kernel

On Thursday 27 April 2006 17:27, Avi Kivity wrote:
> > Where do you see goto-heavy code in kernel?
> >
> >   
> 
> [avi@cleopatra linux]$ grep -rw goto . | wc -l
> 37448
> 
> Repeat without 'wc' to get a detailed listing.

In 1999 Dave 'Barc0de' Jones, Paranoid wierdo noize making geek,
wrote this:

http://www.uwsg.iu.edu/hypermail/linux/kernel/9901.2/0939.html

I failed to find a link, but in 2004 Dave Jones, a well-known
kernel hacker, wrote something like "Wow, it's fun to read
my own old mail, how naive I was back then :)"

Feel free to get your hards dirty with kernel development,
and maybe you will say something similar a few years from now.

Or maybe not, and I will be proven wrong.
--
vda

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 14:27                                     ` Avi Kivity
  2006-04-27 14:56                                       ` Denis Vlasenko
@ 2006-04-27 15:00                                       ` Martin Mares
  2006-04-27 15:31                                         ` Avi Kivity
  2006-04-28 15:51                                       ` Jan Engelhardt
  2 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-04-27 15:00 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

> As an example, you can easily get C++ to inline the hash function in a 
> generic hashtable or the compare in a sort. I dare you to do it in C.

As you wish :-)

http://atrey.karlin.mff.cuni.cz/~mj/tmp/hashtable.h

It's somewhat ugly inside, but an equally strong generic structure build
with templates will be probably even uglier.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Immanuel doesn't pun, he Kant.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-25 17:53                   ` Avi Kivity
  2006-04-25 18:04                     ` Dmitry Torokhov
  2006-04-25 18:08                     ` Valdis.Kletnieks
@ 2006-04-27 15:10                     ` Denis Vlasenko
  2006-04-27 20:15                       ` Willy Tarreau
  2 siblings, 1 reply; 200+ messages in thread
From: Denis Vlasenko @ 2006-04-27 15:10 UTC (permalink / raw)
  To: Avi Kivity; +Cc: dtor_core, Kyle Moffett, Alan Cox, linux-kernel

On Tuesday 25 April 2006 20:53, Avi Kivity wrote:
> Very often one needs to acquire a resource, do something with it, and 
> then free the resource. Here, "resource" can mean a file descriptor, a 
> reference into a reference counted object, or, in our case, a spinlock. 
> And we want "free" to mean "free no matter what", e.g. on a normal path 
> or an exception path.

...

> Additionally, C++ guarantees that if an exception is thrown after 
> spin_lock() is called, then the spin_unlock() will also be called. 
> That's an interesting mechanism by itself.

Life gets even more interesting when you hit another exception
inside destructor(s) being executed due to first one.
Say, spin_unlock() discovers that lock is already unlocked
and does "throw BUG_double_unlock".

Even if you
(a) remember what standard says about it
(b) implemented nested exception handling correctly,
	then you are still left with
(c) let's pray gcc has no bugs in stack unwinding
    and nested exceptions and nested destructor calls.

Mozilla crashes over such things. For Mozilla, crash is not
*that* catastrophic. For OS kernel, it is.
--
vda

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 15:00                                       ` Martin Mares
@ 2006-04-27 15:31                                         ` Avi Kivity
  2006-04-27 15:38                                           ` Martin Mares
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-27 15:31 UTC (permalink / raw)
  To: Martin Mares; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

Martin Mares wrote:
>> As an example, you can easily get C++ to inline the hash function in a 
>> generic hashtable or the compare in a sort. I dare you to do it in C.
>>     
>
> As you wish :-)
>
> http://atrey.karlin.mff.cuni.cz/~mj/tmp/hashtable.h
>   
Touche :)

This is pushing all boundaries, however. That code is horrible.
> It's somewhat ugly inside, but an equally strong generic structure build
> with templates will be probably even uglier.
>
>   
Not at all.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 15:31                                         ` Avi Kivity
@ 2006-04-27 15:38                                           ` Martin Mares
  2006-04-28  8:16                                             ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-04-27 15:38 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

> This is pushing all boundaries, however. That code is horrible.
>
> >It's somewhat ugly inside, but an equally strong generic structure build
> >with templates will be probably even uglier.
> >
> Not at all.

So, show your version :-)

(as fast as this one, of course)

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Outside of a dog, a book is man's best friend. Inside a dog, it's too dark to read.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 14:56                                       ` Denis Vlasenko
@ 2006-04-27 15:54                                         ` Bob Copeland
  2006-04-27 16:03                                         ` Avi Kivity
  1 sibling, 0 replies; 200+ messages in thread
From: Bob Copeland @ 2006-04-27 15:54 UTC (permalink / raw)
  To: Denis Vlasenko; +Cc: Avi Kivity, Kyle Moffett, Roman Kononov, LKML Kernel

On 4/27/06, Denis Vlasenko <vda@ilport.com.ua> wrote:
> On Thursday 27 April 2006 17:27, Avi Kivity wrote:
> > > Where do you see goto-heavy code in kernel?
> > >
> > >
> >
> > [avi@cleopatra linux]$ grep -rw goto . | wc -l
> > 37448
> >
> > Repeat without 'wc' to get a detailed listing.
>
> In 1999 Dave 'Barc0de' Jones, Paranoid wierdo noize making geek,
> wrote this:
>
> http://www.uwsg.iu.edu/hypermail/linux/kernel/9901.2/0939.html
>
> I failed to find a link, but in 2004 Dave Jones, a well-known
> kernel hacker, wrote something like "Wow, it's fun to read
> my own old mail, how naive I was back then :)"

Possibly:

http://marc.theaimsgroup.com/?l=linux-kernel&m=104246373424112

-Bob

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 14:56                                       ` Denis Vlasenko
  2006-04-27 15:54                                         ` Bob Copeland
@ 2006-04-27 16:03                                         ` Avi Kivity
  1 sibling, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-27 16:03 UTC (permalink / raw)
  To: Denis Vlasenko; +Cc: Kyle Moffett, Roman Kononov, LKML Kernel

Denis Vlasenko wrote:
> On Thursday 27 April 2006 17:27, Avi Kivity wrote:
>   
>>> Where do you see goto-heavy code in kernel?
>>>
>>>   
>>>       
>> [avi@cleopatra linux]$ grep -rw goto . | wc -l
>> 37448
>>
>> Repeat without 'wc' to get a detailed listing.
>>     
>
> In 1999 Dave 'Barc0de' Jones, Paranoid wierdo noize making geek,
> wrote this:
>
> http://www.uwsg.iu.edu/hypermail/linux/kernel/9901.2/0939.html
>
> I failed to find a link, but in 2004 Dave Jones, a well-known
> kernel hacker, wrote something like "Wow, it's fun to read
> my own old mail, how naive I was back then :)"
>   

:)

I'll refer you to the 4-line vs 14-line examples. To the C++ trained 
mind, the 4 line segment is much clearer.

> Feel free to get your hards dirty with kernel development,
> and maybe you will say something similar a few years from now.
>   

I have some experience with kernel code (mucking about the asynchronous 
I/O implementation) and a lot of experience in C++ system code (both 
ring 0 and userspace). What I've written in this thread is a result of 
20+ (can't believe I'm writing that number) years of coding, not 
theoretical studies (I've studied aeronautical engineering but practiced 
it very little; if I talk about that maybe you can use the theory vs 
practice argument).

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
                       ` (4 preceding siblings ...)
  2006-04-24 21:38     ` Kurt Wall
@ 2006-04-27 16:17     ` Roman Kononov
  2006-04-27 21:59       ` Grant Coady
  2006-04-27 22:09     ` Bill Davidsen
  6 siblings, 1 reply; 200+ messages in thread
From: Roman Kononov @ 2006-04-27 16:17 UTC (permalink / raw)
  To: linux-kernel

On 04/24/2006 15:02, Gary Poppitz wrote:
>> We know they are "incompatible", why else would we allow "private" and
>> "struct class" in the kernel source if we some how expected it to work
>> with a C++ compiler?
> 
> 
> I can see that this was intentional, not an oversight.
> 
> If there is a childish temper tantrum mentality about C++ then I have no 
> reason or desire to be on this list.
> 
> Grow up.

Please let me summarize:
	1) Many people are more efficient writing C++ modules.
	2) It does not make sense to rewrite existing C code in
	   another language.
	3) Kernel H-files are not compilable by g++.
	4) The H-files use C++ keywords.
	5) The H-files use member initialization syntax, unsupported
	   by g++.
	6) The H-files use empty structures which are not empty in
	   g++.

4), 5) and 6) are to be fixed if we want to be g++-friendly. I am not 
aware of any other issues. Features like static constructors and 
exceptions are not strictly necessary for successful C++ programming.

4) must be trivial.
5) is less trivial but still doable. Can we ask g++ folks?
6) looks rather painful.

What do you think?

Regards
Roman


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback (when does this religious thread end?)
  2006-04-26 23:00                         ` Roman Kononov
                                             ` (2 preceding siblings ...)
  2006-04-27  7:55                           ` Jan-Benedict Glaw
@ 2006-04-27 17:20                           ` Leonard Peterson
  2006-04-30 17:48                           ` C++ pushback Jan Harkes
  4 siblings, 0 replies; 200+ messages in thread
From: Leonard Peterson @ 2006-04-27 17:20 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel

What about support for JAVA-modules in the kernel? Or modules written in C#? 

In my opinion there are many decent languages (just like C++) and I am 
convinced that there are people out there who think that the Linux kernel 
should support any language they can imagine, because it has such and such 
nice/good/robust/etc. feature.

Neither C or C++ sucks, its just the programmer that sucks.

So Please, end this religious discussion, it leads to nowhere...


Leonard

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-27 15:10                     ` Denis Vlasenko
@ 2006-04-27 20:15                       ` Willy Tarreau
  2006-04-27 21:08                         ` Davi Arnaut
  0 siblings, 1 reply; 200+ messages in thread
From: Willy Tarreau @ 2006-04-27 20:15 UTC (permalink / raw)
  To: Denis Vlasenko
  Cc: Avi Kivity, dtor_core, Kyle Moffett, Alan Cox, linux-kernel

On Thu, Apr 27, 2006 at 06:10:07PM +0300, Denis Vlasenko wrote:
> On Tuesday 25 April 2006 20:53, Avi Kivity wrote:
> > Very often one needs to acquire a resource, do something with it, and 
> > then free the resource. Here, "resource" can mean a file descriptor, a 
> > reference into a reference counted object, or, in our case, a spinlock. 
> > And we want "free" to mean "free no matter what", e.g. on a normal path 
> > or an exception path.
> 
> ...
> 
> > Additionally, C++ guarantees that if an exception is thrown after 
> > spin_lock() is called, then the spin_unlock() will also be called. 
> > That's an interesting mechanism by itself.
> 
> Life gets even more interesting when you hit another exception
> inside destructor(s) being executed due to first one.
> Say, spin_unlock() discovers that lock is already unlocked
> and does "throw BUG_double_unlock".
> 
> Even if you
> (a) remember what standard says about it
> (b) implemented nested exception handling correctly,
> 	then you are still left with
> (c) let's pray gcc has no bugs in stack unwinding
>     and nested exceptions and nested destructor calls.
> 
> Mozilla crashes over such things. For Mozilla, crash is not
> *that* catastrophic. For OS kernel, it is.

Mozilla is written in C++ ? I start to better understand where the
160 MB bloat comes from...

> vda

Cheers,
Willy


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-27 20:15                       ` Willy Tarreau
@ 2006-04-27 21:08                         ` Davi Arnaut
  2006-04-28  9:33                           ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Davi Arnaut @ 2006-04-27 21:08 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: Denis Vlasenko, Avi Kivity, dtor_core, Kyle Moffett, Alan Cox,
	linux-kernel

On 4/27/06, Willy Tarreau <willy@w.ods.org> wrote:
> On Thu, Apr 27, 2006 at 06:10:07PM +0300, Denis Vlasenko wrote:
> > On Tuesday 25 April 2006 20:53, Avi Kivity wrote:
> > > Very often one needs to acquire a resource, do something with it, and
> > > then free the resource. Here, "resource" can mean a file descriptor, a
> > > reference into a reference counted object, or, in our case, a spinlock.
> > > And we want "free" to mean "free no matter what", e.g. on a normal path
> > > or an exception path.
> >
> > ...
> >
> > > Additionally, C++ guarantees that if an exception is thrown after
> > > spin_lock() is called, then the spin_unlock() will also be called.
> > > That's an interesting mechanism by itself.
> >
> > Life gets even more interesting when you hit another exception
> > inside destructor(s) being executed due to first one.
> > Say, spin_unlock() discovers that lock is already unlocked
> > and does "throw BUG_double_unlock".
> >
> > Even if you
> > (a) remember what standard says about it
> > (b) implemented nested exception handling correctly,
> >       then you are still left with
> > (c) let's pray gcc has no bugs in stack unwinding
> >     and nested exceptions and nested destructor calls.
> >
> > Mozilla crashes over such things. For Mozilla, crash is not
> > *that* catastrophic. For OS kernel, it is.
>
> Mozilla is written in C++ ? I start to better understand where the
> 160 MB bloat comes from...

Evolution is written in C.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 16:17     ` Roman Kononov
@ 2006-04-27 21:59       ` Grant Coady
  0 siblings, 0 replies; 200+ messages in thread
From: Grant Coady @ 2006-04-27 21:59 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel

On Thu, 27 Apr 2006 11:17:58 -0500, Roman Kononov <kononov195-far@yahoo.com> wrote:

>Please let me summarize:
>	1) Many people are more efficient writing C++ modules.
>	2) It does not make sense to rewrite existing C code in
>	   another language.
>	3) Kernel H-files are not compilable by g++.
>	4) The H-files use C++ keywords.
>	5) The H-files use member initialization syntax, unsupported
>	   by g++.
>	6) The H-files use empty structures which are not empty in
>	   g++.
>
>4), 5) and 6) are to be fixed if we want to be g++-friendly. I am not 
>aware of any other issues. Features like static constructors and 
>exceptions are not strictly necessary for successful C++ programming.
>
>4) must be trivial.
>5) is less trivial but still doable. Can we ask g++ folks?
>6) looks rather painful.
>
>What do you think?

There's a document: CodingStyle

You seem to be arguing where the kernelspace / userspace boundary 
line is.  C++ is outside kernelspace.

Grant.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-24 20:02   ` C++ pushback Gary Poppitz
                       ` (5 preceding siblings ...)
  2006-04-27 16:17     ` Roman Kononov
@ 2006-04-27 22:09     ` Bill Davidsen
  2006-04-27 23:19       ` Jan Knutar
  6 siblings, 1 reply; 200+ messages in thread
From: Bill Davidsen @ 2006-04-27 22:09 UTC (permalink / raw)
  To: Gary Poppitz, Linux Kernel Mailing List

Gary Poppitz wrote:
>> We know they are "incompatible", why else would we allow "private" and
>> "struct class" in the kernel source if we some how expected it to work
>> with a C++ compiler?
> 
> 
> I can see that this was intentional, not an oversight.

Possibly, what difference would it make?
> 
> If there is a childish temper tantrum mentality about C++ then I have no 
> reason or desire to be on this list.

I only see one temper tantrum, and when you leave there will be none. 
Oh, FORTRAN, PASCAL, and LISP aren't compatible either. And the comments 
are all in English, without subtitles, how can people from other 
cultures ever cope? Answer: nicely, it takes a native speaker of the 
language to really botch the grammar.
> 
> Grow up.

You're whining because the kernel wasn't written for your convenience 
and you tell US to grow up? Someone needs a time out.
-- 
    -bill davidsen (davidsen@tmr.com)
"The secret to procrastination is to put things off until the
  last possible moment - but no longer"  -me

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  1:30             ` linux-os (Dick Johnson)
  2006-04-25  2:58               ` marty fouts
@ 2006-04-27 22:55               ` Bill Davidsen
  2006-05-02 15:58                 ` Randy.Dunlap
  2006-05-02 20:36                 ` David Schwartz
  1 sibling, 2 replies; 200+ messages in thread
From: Bill Davidsen @ 2006-04-27 22:55 UTC (permalink / raw)
  To: linux-os (Dick Johnson); +Cc: Alan Cox, Linux-Kernel, 

linux-os (Dick Johnson) wrote:
> On Mon, 24 Apr 2006, J.A. Magallon wrote:
> 
>> On Mon, 24 Apr 2006 22:52:12 +0100, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>>
>>> On Llu, 2006-04-24 at 15:36 -0600, Jeff V. Merkey wrote:
>>>> C++ in the kernel is a BAD IDEA. C++ code can be written in such a
>>>> convoluted manner as to be unmaintainable and unreadable.
>>> So can C.
>>>
>>>> All of the hidden memory allocations from constructor/destructor
>>>> operatings can and do KILL OS PERFORMANCE.
>>> This is one area of concern. Just as big a problem for the OS case is
>>> that the hidden constructors/destructors may fail.
>> Tell me what is the difference between:

...clear readable code...
>>
>> and
>>
>>    SuperBlock() : s_mount_opt(0), s_resuid(EXT3_DEF_RESUID), s_resgid(EXT3_DEF_RESGID)
>>    {}
...double bagger...

> I'd like to write modules in FORTRAN, myself. Unless you have been
> writing software since computers were programmed with diode-pins, one
> tends to think that the first programming language learned is the
> best. It's generally because they are all bad, and once you learn how
> to make the defective language do what you want, you tend to identify
> with it. Identifying with one's captors, the Stockholm syndrome,
> that's what these languages cause.

No, I wouldn't touch any of the early languages I learned, the first one 
I liked was ALGOL-60. The software for GE's first CT scanner was 
developed in ALGOL-60. I liked PL/1 when GE was part of the MULTICS 
project, and the whole BCPL->B->C family was fun, although I do like C 
best. GE had an implementation language called I-language which was a 
great system language, but they buried it instead of releasing it. I 
hated FORTRAN, LISP and APL, although I wrote a lot of each, predicted 
that Ada would not be popular, but I like PERL. I wrote text tools in 
TRAC (look that one up ;-) but that's kind of all it did well.

If you hadn't made this next point I would have...
> 
> But, a master carpenter has many tools. He chooses the best for each
> task. When you need to make computer hardware do what you want, in
> a defined manner, in the particular order in which you require,
> you use assembly language to generate the exact machine-code required.
> It is possible to compromise a bit and use a slightly higher-level
> procedural language called C. One loses control of everything with
> any other language. Note that before C was invented, all operating
> system code was written in assembly.

Hate to tell you, C came about a decade after MULTICS was written in 
PL/1, and I think DEC had VMS out in BLISS before C. C came from B (as 
did IMP68), which came from BCPL.
> 
> C++ wasn't written for this kind of work. It was written so that a
> programmer didn't have to care how something was done only that somehow
> it would get done. Also, as you peel away the onion skins from many
> C++ graphics libraries, you find inside the core that does the work.
> It's usually written in C.

C++ allows more abstraction than C, unfortunately too many people go 
right past past abstraction to obfuscation. With operator overloading 
it's possible to generate write-only code, and programs where "A=B+C" 
does file operations :-( That doesn't belong in an operating system, C 
is the right choice.

Sorry for the history lesson, you got me thinking about my first languages.

-- 
    -bill davidsen (davidsen@tmr.com)
"The secret to procrastination is to put things off until the
  last possible moment - but no longer"  -me


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 22:09     ` Bill Davidsen
@ 2006-04-27 23:19       ` Jan Knutar
  0 siblings, 0 replies; 200+ messages in thread
From: Jan Knutar @ 2006-04-27 23:19 UTC (permalink / raw)
  To: Bill Davidsen; +Cc: Gary Poppitz, Linux Kernel Mailing List

On Friday 28 April 2006 01:09, Bill Davidsen wrote:

> Oh, FORTRAN, PASCAL, and LISP aren't compatible either. And the comments 

Wasn't there a patch for LISP in the kernel? I seem to remember such a thread...

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 15:38                                           ` Martin Mares
@ 2006-04-28  8:16                                             ` Avi Kivity
  2006-04-28  8:30                                               ` Avi Kivity
  2006-04-28 15:47                                               ` Jan Engelhardt
  0 siblings, 2 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-28  8:16 UTC (permalink / raw)
  To: Martin Mares; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

Martin Mares wrote:
>> This is pushing all boundaries, however. That code is horrible.
>>
>>     
>>> It's somewhat ugly inside, but an equally strong generic structure build
>>> with templates will be probably even uglier.
>>>
>>>       
>> Not at all.
>>     
>
> So, show your version :-)
>
> (as fast as this one, of course)
>
> 				Have a nice fortnight
>   
Here you go. In practice one would probably uninline get() and possibly put().

It doesn't do all that your example does (a 15 minute hack), but it is easily expandable. It 
also allows a value to belong to two different hash tables (on two different keys) simultaneously.

#include <cassert>

template <typename Key, class Value, class Traits>
class Hashtable
{
public:
    class Link {
    private:
        Link* next;
        Value& value()
        {
            return *static_cast<Value*>(this);
        }
        friend class Hashtable;
    };
public:
    explicit Hashtable(int size)
        : _size(size)
        , _buckets(new Link[size])
    {
        assert((_size & (_size -  1)) == 0);
    }
    ~Hashtable()
    {
        delete[] _buckets;
    }
    Value* get(const Key& key)
    {
        Link* link = _buckets[Traits::hash(key) & (_size - 1)].next;
        while (link && !Traits::equal(key, link->value()))
            link = link->next;
        if (link)
            return &link->value();
        return 0;
    }
    void put(Value& value)
    {
        // assumes value (or a value with an equal key) is not already in
        Link& head = _buckets[Traits::hash(value) & (_size - 1)];
        static_cast<Link&>(value).next = &head;
        head.next= &value;
    }
private:
    int _size;
    Link* _buckets;
};

// example program

#include <iostream>
#include <string.h>

struct Word;
struct WordHashTraits;
typedef Hashtable<const char*, Word, WordHashTraits> WordHash;

struct Word : WordHash::Link
{
    explicit Word(const char* _word) : word(_word), count(0) {}
    const char* word;
    int count;
};

struct WordHashTraits
{
    static unsigned hash(const char* key)
    {
        // assume this is jenkin's hash.
        unsigned h = 0;
        while (*key) {
            h = (h << 3) | (h >> 29);
            h ^= (unsigned char)*key++;
        }
        return h;
    }
    static unsigned hash(const Word& value)
    {
        return hash(value.word);
    }
    static bool equal(const char* key, const Word& value)
    {
        return strcmp(key, value.word) == 0;
    }
};

int main(int ac, const char** av)
{
    WordHash hashtable(16); // make collisions likely
    for (int i = 1; i < ac; ++i) {
        const char* word = av[i];
        Word* word_in_hash = hashtable.get(word);
        if (!word_in_hash) {
            word_in_hash = new Word(word);
            hashtable.put(*word_in_hash);
        }
        ++word_in_hash->count;
        std::cout << "word: " << word << " count " << word_in_hash->count << "\n";
    }
}









-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-28  8:16                                             ` Avi Kivity
@ 2006-04-28  8:30                                               ` Avi Kivity
  2006-04-28 15:47                                               ` Jan Engelhardt
  1 sibling, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-28  8:30 UTC (permalink / raw)
  To: Martin Mares; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

Avi Kivity wrote:
>    void put(Value& value)
>    {
>        // assumes value (or a value with an equal key) is not already in
>        Link& head = _buckets[Traits::hash(value) & (_size - 1)];
>        static_cast<Link&>(value).next = &head;
>        head.next= &value;
>    }
s/&head/head.next/ in the third line, of course.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 21:37                           ` Sam Ravnborg
@ 2006-04-28  9:23                             ` Avi Kivity
  2006-04-28 12:00                               ` linux-os (Dick Johnson)
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-28  9:23 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Al Viro, Linus Torvalds, Jan-Benedict Glaw, linux-kernel, David Schwartz

Sam Ravnborg wrote:
> The original question was related to port existing C++ code to be used
> as a kernel module.
> Magically this always ends up in long discussions about how applicable
> C++ is the the kernel as such which was not the original intent.
>
> So following the original intent it does not matter what subset is
> sanely used, only what adaptions is needed to kernel proper to support
> modules written in C++.
>
>   

Here at last is a sane response. If the kernel were enhanced/bastardized 
(pick one) to support C++ modules, we could evaluate how C++ actually 
does in terms of runtime and developer performance.

> But I have seen no patches this time either, so required modifications
> are yet to be identified.
>   

Since such patches are sure to be rejected (apparently renaming 'struct 
class' would wreak havoc on the development process), I doubt that they 
will appear. Not to mention the attacks on the submitters that would follow.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-27 21:08                         ` Davi Arnaut
@ 2006-04-28  9:33                           ` Avi Kivity
  2006-04-28 10:03                             ` Avi Kivity
  2006-04-28 11:03                             ` Martin Mares
  0 siblings, 2 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-28  9:33 UTC (permalink / raw)
  To: Davi Arnaut
  Cc: Willy Tarreau, Denis Vlasenko, dtor_core, Kyle Moffett, Alan Cox,
	linux-kernel

Davi Arnaut wrote:
>>
>> Mozilla is written in C++ ? I start to better understand where the
>> 160 MB bloat comes from...
>>     
>
> Evolution is written in C.
>   

FWIW, userspace is moving away from C as unproductive and unsafe. KDE is 
of course C++, mozilla, openoffice are C++, and gnome is moving towards 
(of all things) C#.

GCC considered adopting a C++ subset. My impressions of the discussion 
was that (a) a majority of the developers would like that (b) RMS would 
never allow it (c) there were concerns about bootstrap on platforms 
where a C++ compiler was not available.

Kernels of other operating systems (Windows, AIX (?)) allow C++. And 
don't start about Windows crashing whenever you sneeze at it - it's so 1998.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28  9:33                           ` Avi Kivity
@ 2006-04-28 10:03                             ` Avi Kivity
  2006-04-28 11:27                               ` Sergei Organov
  2006-04-28 11:03                             ` Martin Mares
  1 sibling, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-28 10:03 UTC (permalink / raw)
  To: Davi Arnaut
  Cc: Willy Tarreau, Denis Vlasenko, dtor_core, Kyle Moffett, Alan Cox,
	linux-kernel

Avi Kivity wrote:
>
> Kernels of other operating systems (Windows, AIX (?)) allow C++. And 
> don't start about Windows crashing whenever you sneeze at it - it's so 
> 1998.
>

Oh, and it looks like some guy even wrote a kernel [1] in C++! Lucky we 
don't have people like that working on Linux.

[1] http://www.zipworld.com.au/~akpm/#rtos


(Sorry, couldn't resist)

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28  9:33                           ` Avi Kivity
  2006-04-28 10:03                             ` Avi Kivity
@ 2006-04-28 11:03                             ` Martin Mares
  2006-04-28 11:30                               ` Avi Kivity
  2006-04-30 21:15                               ` Eric W. Biederman
  1 sibling, 2 replies; 200+ messages in thread
From: Martin Mares @ 2006-04-28 11:03 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Davi Arnaut, Willy Tarreau, Denis Vlasenko, dtor_core,
	Kyle Moffett, Alan Cox, linux-kernel

> FWIW, userspace is moving away from C as unproductive and unsafe. KDE is 
> of course C++, mozilla, openoffice are C++, and gnome is moving towards 
> (of all things) C#.

Maybe continuing to write application programs in C instead of using
higher-level languages is silly and backward, but _stopping_ at the
level of C++ or C# is equally silly.

However, in the kernel space the main problems the people are spending
their time with are rarely related to the language.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Q: Do you believe in One God? A: Yes, up to isomorphism.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 10:03                             ` Avi Kivity
@ 2006-04-28 11:27                               ` Sergei Organov
  0 siblings, 0 replies; 200+ messages in thread
From: Sergei Organov @ 2006-04-28 11:27 UTC (permalink / raw)
  To: Avi Kivity; +Cc: linux-kernel

Avi Kivity <avi@argo.co.il> writes:

> Avi Kivity wrote:
>>
>> Kernels of other operating systems (Windows, AIX (?)) allow C++. And
>> don't start about Windows crashing whenever you sneeze at it - it's
>> so 1998.
>>
>
> Oh, and it looks like some guy even wrote a kernel [1] in C++! Lucky
> we don't have people like that working on Linux.
>
> [1] http://www.zipworld.com.au/~akpm/#rtos

FYI, the core of another, more widely used open-source RTOS, eCos [2],
is written in C++ as well though it supports C for drivers development
and its public interface is C wrapper around the C++ core.

On the other hand, I think I do understand Linux hackers` worries about
C++ leaking into the Linux kernel. For many supporting C++, even in the
modules only, is only slightly different from supporting binary drivers,
I guess. That could be in fact very serious problem, I'm afraid.

[2] <http://ecos.sourceware.org/>

-- 
Sergei.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 11:03                             ` Martin Mares
@ 2006-04-28 11:30                               ` Avi Kivity
  2006-04-28 15:56                                 ` Jan Engelhardt
  2006-04-30 21:15                               ` Eric W. Biederman
  1 sibling, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-28 11:30 UTC (permalink / raw)
  To: Martin Mares
  Cc: Davi Arnaut, Willy Tarreau, Denis Vlasenko, dtor_core,
	Kyle Moffett, Alan Cox, linux-kernel

Martin Mares wrote:
> Maybe continuing to write application programs in C instead of using
> higher-level languages is silly and backward, but _stopping_ at the
> level of C++ or C# is equally silly.
>
>   

Agree. Look at how well mercurial turned out compared to git, and it is 
written in such a slow language.

The high level language allows you to concentrate on the algorithms 
which is where the performance comes from.

> However, in the kernel space the main problems the people are spending
> their time with are rarely related to the language.
>   

If you're using a more productive language, you get more things done, in 
userspace and in the kernel.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-28  9:23                             ` Avi Kivity
@ 2006-04-28 12:00                               ` linux-os (Dick Johnson)
  2006-04-28 12:46                                 ` Jan-Benedict Glaw
  0 siblings, 1 reply; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-28 12:00 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Sam Ravnborg, Al Viro, Linus Torvalds, Jan-Benedict Glaw,
	linux-kernel, David Schwartz


On Fri, 28 Apr 2006, Avi Kivity wrote:

> Sam Ravnborg wrote:
>> The original question was related to port existing C++ code to be used
>> as a kernel module.
>> Magically this always ends up in long discussions about how applicable
>> C++ is the the kernel as such which was not the original intent.
>>
>> So following the original intent it does not matter what subset is
>> sanely used, only what adaptions is needed to kernel proper to support
>> modules written in C++.
>>
>>
>
> Here at last is a sane response. If the kernel were enhanced/bastardized
> (pick one) to support C++ modules, we could evaluate how C++ actually
> does in terms of runtime and developer performance.
>
>> But I have seen no patches this time either, so required modifications
>> are yet to be identified.
>>
>
> Since such patches are sure to be rejected (apparently renaming 'struct
> class' would wreak havoc on the development process), I doubt that they
> will appear. Not to mention the attacks on the submitters that would follow.
>

I'm fairly sure that if header structure members were renamed (one
patch at a time), and were renamed sanely (like struct class should not
be renamed to struct TheyDidntKnowAnything)... and sanely also means
trying to have the same length like (struct klass)...and if every file
that included those headers were updated.... I think the patches would
not be rejected, especially if Linus said, "Let's get rid of the
C++ keywords."

It is well known that in a few years you won't be able to find a 'C'
compiler or C++ for that matter. Everything will be written in Z##
or whatever. The problem I see is that newcomers, who have only
learned one language, assume that they have some special enlightenment
and that 'C' is wrong. Simple changes that let these newcomers experiment,
perhaps finding the errors of their ways, as long as they are not
harmful, should not be discouraged.

Maybe it's fork time, but maybe not. There seem to be very few C++
keywords being used although, where they are used, affect many files.
If it was my ballgame, I'd let the C++ advocates submit patches to
remove those keywords. Then, after they get their first module
to load, they will learn the errors of their ways as they find
that there isn't enough RAM available to do any useful work. But,
at least the "bad" words will have been removed from the headers
by highly motivated programmers. The cost is zero.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
New book: http://www.lymanschool.com
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-28 12:00                               ` linux-os (Dick Johnson)
@ 2006-04-28 12:46                                 ` Jan-Benedict Glaw
  0 siblings, 0 replies; 200+ messages in thread
From: Jan-Benedict Glaw @ 2006-04-28 12:46 UTC (permalink / raw)
  To: linux-os (Dick Johnson)
  Cc: Avi Kivity, Sam Ravnborg, Al Viro, Linus Torvalds, linux-kernel,
	David Schwartz

[-- Attachment #1: Type: text/plain, Size: 788 bytes --]

On Fri, 2006-04-28 08:00:17 -0400, linux-os (Dick Johnson) <linux-os@analogic.com> wrote:
> I'm fairly sure that if header structure members were renamed (one
> patch at a time), and were renamed sanely (like struct class should not
> be renamed to struct TheyDidntKnowAnything)... and sanely also means
> trying to have the same length like (struct klass)...and if every file

*cough* This is the Linux Kernel, not a KDE application...

MfG, JBG

-- 
Jan-Benedict Glaw       jbglaw@lug-owl.de    . +49-172-7608481             _ O _
"Eine Freie Meinung in  einem Freien Kopf    | Gegen Zensur | Gegen Krieg  _ _ O
 für einen Freien Staat voll Freier Bürger"  | im Internet! |   im Irak!   O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-28  8:16                                             ` Avi Kivity
  2006-04-28  8:30                                               ` Avi Kivity
@ 2006-04-28 15:47                                               ` Jan Engelhardt
  1 sibling, 0 replies; 200+ messages in thread
From: Jan Engelhardt @ 2006-04-28 15:47 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Martin Mares, Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

> #include <cassert>
>
> template <typename Key, class Value, class Traits>
> class Hashtable
> {
> public:
> class Link {

Does not match CodingStyle. SCNR.

>   assert((_size & (_size -  1)) == 0);

Names with underscores are usually reserved.

> // example program
>
> static unsigned hash(const char* key)
> {
> // assume this is jenkin's hash.
> unsigned h = 0;
> while (*key) {
> h = (h << 3) | (h >> 29);
> h ^= (unsigned char)*key++;

No const_cast<> and static_cast<> here?



Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 14:27                                     ` Avi Kivity
  2006-04-27 14:56                                       ` Denis Vlasenko
  2006-04-27 15:00                                       ` Martin Mares
@ 2006-04-28 15:51                                       ` Jan Engelhardt
  2006-04-28 16:51                                         ` Avi Kivity
  2 siblings, 1 reply; 200+ messages in thread
From: Jan Engelhardt @ 2006-04-28 15:51 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

>
> It still can't typecheck void pointers. With C++ they're very rare.
>
Using C++ just because one can't verify that all type conversions in a C 
program from/to void* are as they are supposed to be is... well, think of 
something.


Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 11:30                               ` Avi Kivity
@ 2006-04-28 15:56                                 ` Jan Engelhardt
  2006-04-28 17:02                                   ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Jan Engelhardt @ 2006-04-28 15:56 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Martin Mares, Davi Arnaut, Willy Tarreau, Denis Vlasenko,
	dtor_core, Kyle Moffett, Alan Cox, linux-kernel

>
> The high level language allows you to concentrate on the algorithms which is
> where the performance comes from.
>
Do you consider e.g. Perl or Python highlevel?
If so: I doubt that's where performance can come from. Ever. (Unless you 
cheat by using XS.)


Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-28 15:51                                       ` Jan Engelhardt
@ 2006-04-28 16:51                                         ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-04-28 16:51 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Denis Vlasenko, Kyle Moffett, Roman Kononov, LKML Kernel

Jan Engelhardt wrote:
>> It still can't typecheck void pointers. With C++ they're very rare.
>>
>>     
> Using C++ just because one can't verify that all type conversions in a C 
> program from/to void* are as they are supposed to be is... well, think of 
> something.
>   

If you remove the 'just', I'd say 'a way to catch more bugs at compile 
time'.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 15:56                                 ` Jan Engelhardt
@ 2006-04-28 17:02                                   ` Avi Kivity
  2006-04-28 17:38                                     ` linux-os (Dick Johnson)
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-04-28 17:02 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: Martin Mares, Davi Arnaut, Willy Tarreau, Denis Vlasenko,
	dtor_core, Kyle Moffett, Alan Cox, linux-kernel

Jan Engelhardt wrote:
>> The high level language allows you to concentrate on the algorithms which is
>> where the performance comes from.
>>     
> Do you consider e.g. Perl or Python highlevel?
>   

I once wrote Perl. I deeply regret the experience. But yes, they are 
both high(er) level. There are even higher levels to aspire to.

> If so: I doubt that's where performance can come from. Ever. (Unless you 
> cheat by using XS.)
>   

Given infinite time, patience, and concentration, the C or C++ program 
will always win over Python; as assembly will win over C or C++.

If your time is bounded, your Python code might be running while you're 
still typing in your C code, you're be profiling and making changes to 
the alghorithm in Python while hunting for that mysterious segmentation 
fault in C (thank goodness for valgrind), and adding multithreading to 
the third and final version of your Python code while debating whether 
to buy more memory or sit down and chase that memory leak.

Developer performance equates to runtime performance.

ps. Yes, that wouldn't work for a simple example like counting words in 
a file. Try something more complex, like an SCM system.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 17:02                                   ` Avi Kivity
@ 2006-04-28 17:38                                     ` linux-os (Dick Johnson)
  2006-04-29  2:50                                       ` Christer Weinigel
  2006-05-01 17:46                                       ` Dave Neuer
  0 siblings, 2 replies; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-04-28 17:38 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Jan Engelhardt, Martin Mares, Davi Arnaut, Willy Tarreau,
	Denis Vlasenko, dtor_core, Kyle Moffett, Alan Cox, linux-kernel


On Fri, 28 Apr 2006, Avi Kivity wrote:

> Jan Engelhardt wrote:
>>> The high level language allows you to concentrate on the algorithms which is
>>> where the performance comes from.
>>>
>> Do you consider e.g. Perl or Python highlevel?
>>
>
> I once wrote Perl. I deeply regret the experience. But yes, they are
> both high(er) level. There are even higher levels to aspire to.
>
>> If so: I doubt that's where performance can come from. Ever. (Unless you
>> cheat by using XS.)
>>
>
> Given infinite time, patience, and concentration, the C or C++ program
> will always win over Python; as assembly will win over C or C++.
>
> If your time is bounded, your Python code might be running while you're
> still typing in your C code, you're be profiling and making changes to
> the alghorithm in Python while hunting for that mysterious segmentation
> fault in C (thank goodness for valgrind), and adding multithreading to
> the third and final version of your Python code while debating whether
> to buy more memory or sit down and chase that memory leak.
>
> Developer performance equates to runtime performance.
>

Read what you wrote! It's absolutely, incredibly stupid!

The cost in developer time is borne once. The cost of performance
is borne every time you run the application.

> ps. Yes, that wouldn't work for a simple example like counting words in
> a file. Try something more complex, like an SCM system.
>
> --
> Do not meddle in the internals of kernels, for they are subtle and quick to panic.
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
New book: http://www.lymanschool.com
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 17:38                                     ` linux-os (Dick Johnson)
@ 2006-04-29  2:50                                       ` Christer Weinigel
  2006-05-01 17:46                                       ` Dave Neuer
  1 sibling, 0 replies; 200+ messages in thread
From: Christer Weinigel @ 2006-04-29  2:50 UTC (permalink / raw)
  To: linux-os (Dick Johnson); +Cc: Avi Kivity, linux-kernel

[trimming the Cc list since probably nobody is interested in yet
another language flame]

"linux-os \(Dick Johnson\)" <linux-os@analogic.com> writes:

> On Fri, 28 Apr 2006, Avi Kivity wrote:
> > Developer performance equates to runtime performance.
> 
> Read what you wrote! It's absolutely, incredibly stupid!
> 
> The cost in developer time is borne once. The cost of performance
> is borne every time you run the application.

That last sentence is true.  The rest is you misunderstanding him.

Yes, for some things it is worth hand optimizing until you're blue in
the face, but most of the time the language doesn't matter at all.  No
matter what you do, 99% of the execution time will be spent waiting
for disk or waiting for user input.

Even if the task is CPU bound, a higher level language (C++/STL,
Python, Perl, vhatever) may be faster than most C implementations
because the time spent in the high level language is insignificant
compared to the time spent in the highly optimized libraries that come
with those languages (e.g. the regexp stuff in perl).  

And even if there is no optimized library it may still be better to
develop in a higher level language because the algorithms used may be
clearer than the same code in C because the C code needs so much
manual bookkeping to work.  If the algorithm is easier to understand
it is usually also easier to optimize, and remember that algorithmic
optimizations usually give magnitudes of better performance, while low
level optimizatios just provide a few percent.

Another thing to consider is that at program that always completes
successfully, although a bit slow, is usually a lot better than a
program that is fast for most data sets but segfaults for some others.
It is much too easy to make a simple off-by-one mistake in C or forget
to free some memory and get a memory leak.  A really good C programmer
will not make that kind of mistakes all that often, and with good C
libraries and a good program structure a C application can also be
easy to understand and optimize, but lets face it, most C programmers
and C programs aren't all that good.

With all that said, I personally belive that coding the kernel in C
and assembly is a very good choice.  The performance of the kernel
affects every application on the system, so saving a few bytes of
memory in a page table descriptor or a some tenths of a percent in a
hot path will mean a huge gain for the system as a whole.  And the
kernel maintainers are a bunch of extremely talented people who do a
tremendous job of keeping the kernel clean and maintainable.  With
almost 15 years of development spent on the kernel written in C, they
are starting to understand what works and what doesn't work.  If we
try to implement parts of the kernel in C++, we'll have to spend
another 10 years learning what works and doesn't work in C++. [1]

So for some things, such as the kernel, very resource constrained
systems, libraries that everyone use, C is a good choice.  But blindly
choosing C, based on some naive belief that C is always more
performant, that is just plain stupid.

Sorry for the rant, but this particular subject is a just a particular
itch of mine.

  /Christer (who prefers programming C and Python)

[1] Recommended reading: Safer C by Les Hatton.

> The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

This part of legalese is just plain silly, if you didn't want the
world to read your mails, don't post to public mailing lists.

-- 
"Just how much can I get away with and still go to heaven?"

Freelance consultant specializing in device driver programming for Linux 
Christer Weinigel <christer@weinigel.se>  http://www.weinigel.se

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-26 23:00                         ` Roman Kononov
                                             ` (3 preceding siblings ...)
  2006-04-27 17:20                           ` C++ pushback (when does this religious thread end?) Leonard Peterson
@ 2006-04-30 17:48                           ` Jan Harkes
  2006-04-30 20:55                             ` David Schwartz
  4 siblings, 1 reply; 200+ messages in thread
From: Jan Harkes @ 2006-04-30 17:48 UTC (permalink / raw)
  To: Roman Kononov; +Cc: linux-kernel

On Wed, Apr 26, 2006 at 06:00:52PM -0500, Roman Kononov wrote:
> Linus Torvalds wrote:
> > - a lot of the C++ features just won't be supported sanely (ie the kernel 
> >   infrastructure just doesn't do exceptions for C++, nor will it run any 
> >   static constructors etc).
> A lot of C++ features are already supported sanely. You simply need to 
> understand them. Especially templates and type checking. C++ 
> exceptions are not very useful tool in kernels. Static constructor 
> issue is trivial. I use all C++ features (except exceptions) in all 
> projects: Linux kernel modules, embedded real-time applications, 
> everywhere. They _really_ help a lot.

Seriously, your code must be broken.

The C++ standard does not allow an allocator to return NULL, it is
supposed to raise an exception.

Jan


^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-30 17:48                           ` C++ pushback Jan Harkes
@ 2006-04-30 20:55                             ` David Schwartz
  0 siblings, 0 replies; 200+ messages in thread
From: David Schwartz @ 2006-04-30 20:55 UTC (permalink / raw)
  To: jaharkes; +Cc: linux-kernel


> The C++ standard does not allow an allocator to return NULL, it is
> supposed to raise an exception.
>
> Jan

	It is not that unusual for C++ projects to use no exceptions at all. They
simply replace the default standardized allocators with their own. These
allocators can do whatever you want when memory runs out, including waiting
until more memory is available while acting to reduce memory usage in other
parts of the program.

	You are not forced to use exceptions if you don't want to. Personally, I
don't like them, and I rarely use them, even in large C++ projects (hundreds
of thousands of lines).

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 11:03                             ` Martin Mares
  2006-04-28 11:30                               ` Avi Kivity
@ 2006-04-30 21:15                               ` Eric W. Biederman
  1 sibling, 0 replies; 200+ messages in thread
From: Eric W. Biederman @ 2006-04-30 21:15 UTC (permalink / raw)
  To: Martin Mares
  Cc: Avi Kivity, Davi Arnaut, Willy Tarreau, Denis Vlasenko,
	dtor_core, Kyle Moffett, Alan Cox, linux-kernel

Martin Mares <mj@ucw.cz> writes:

>> FWIW, userspace is moving away from C as unproductive and unsafe. KDE is 
>> of course C++, mozilla, openoffice are C++, and gnome is moving towards 
>> (of all things) C#.
>
> Maybe continuing to write application programs in C instead of using
> higher-level languages is silly and backward, but _stopping_ at the
> level of C++ or C# is equally silly.
>
> However, in the kernel space the main problems the people are spending
> their time with are rarely related to the language.

To some extent that is true.  There is a huge amount of work involved
with understanding the hardware.

The things we need to check in the kernel don't seem to coincide
to facility provided by any current programming language.  I can't get
the compiler to check that I don't overflow a 4K stack,  that I always
use the same permissions checks to guard the same class of objects,
that my aggressive refactoring didn't miss a subtle dependency by the
users of that code. 

Currently every language I know of are variations on a theme, that
helps to write applications and abstractions, but provides little
help in verifying those abstractions.   In essence what is
needed are compile to assertion checking.

Languages like C++ do seem to make it easier to get to a higher
level of abstraction, and share fundamental abstractions like
your object system with a large body of programs.  However once
you are at that level of abstraction in a language current languages
don't seem to provide much real additional help.

So I do agree that the improvement by a language switch is limited
by Amdahl's law, and since most coding time is spent thinking and
testing a language needs to show major gains in at least one
of those areas to really show improvement.

I think it is possible to show major gains in testing but I have
yet to see a language that address that issue.  C++ with it's slower
compiler, and greater complexity clearly will neither increase 
the frequency of tests nor the number of people qualified to review
the code.

Eric

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-04-28 17:38                                     ` linux-os (Dick Johnson)
  2006-04-29  2:50                                       ` Christer Weinigel
@ 2006-05-01 17:46                                       ` Dave Neuer
  2006-05-01 20:21                                         ` Jan Engelhardt
  2006-05-01 23:53                                         ` David Schwartz
  1 sibling, 2 replies; 200+ messages in thread
From: Dave Neuer @ 2006-05-01 17:46 UTC (permalink / raw)
  To: linux-os (Dick Johnson)
  Cc: Avi Kivity, Jan Engelhardt, Martin Mares, Davi Arnaut,
	Willy Tarreau, Denis Vlasenko, dtor_core, Kyle Moffett, Alan Cox,
	linux-kernel

On 4/28/06, linux-os (Dick Johnson) <linux-os@analogic.com> wrote:
>
> On Fri, 28 Apr 2006, Avi Kivity wrote:
> >
> > If your time is bounded, your Python code might be running while you're
> > still typing in your C code, you're be profiling and making changes to
> > the alghorithm in Python while hunting for that mysterious segmentation
> > fault in C (thank goodness for valgrind), and adding multithreading to
> > the third and final version of your Python code while debating whether
> > to buy more memory or sit down and chase that memory leak.
> >
> > Developer performance equates to runtime performance.
> >
>
> Read what you wrote! It's absolutely, incredibly stupid!
>
> The cost in developer time is borne once. The cost of performance
> is borne every time you run the application.

The cost in developer time is borne every time someone needs to modify the code.

Dave

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-01 17:46                                       ` Dave Neuer
@ 2006-05-01 20:21                                         ` Jan Engelhardt
  2006-05-01 23:53                                         ` David Schwartz
  1 sibling, 0 replies; 200+ messages in thread
From: Jan Engelhardt @ 2006-05-01 20:21 UTC (permalink / raw)
  To: Dave Neuer
  Cc: linux-os (Dick Johnson),
	Avi Kivity, Martin Mares, Davi Arnaut, Willy Tarreau,
	Denis Vlasenko, dtor_core, Kyle Moffett, Alan Cox, linux-kernel

>> 
>> The cost in developer time is borne once. The cost of performance
>> is borne every time you run the application.
>
> The cost in developer time is borne every time someone needs to modify the
> code.
>
The clever developer can cope with both situations.


Jan Engelhardt
-- 

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: Compiling C++ modules
  2006-05-01 17:46                                       ` Dave Neuer
  2006-05-01 20:21                                         ` Jan Engelhardt
@ 2006-05-01 23:53                                         ` David Schwartz
  2006-05-02  5:12                                           ` Willy Tarreau
  2006-05-03 13:13                                           ` Mark Lord
  1 sibling, 2 replies; 200+ messages in thread
From: David Schwartz @ 2006-05-01 23:53 UTC (permalink / raw)
  To: Linux-Kernel@Vger. Kernel. Org


> > The cost in developer time is borne once. The cost of performance
> > is borne every time you run the application.

> The cost in developer time is borne every time someone needs to
> modify the code.

	Or understand the code. Or debug the code. Or verify that the code operates
correctly. Or reuse the code for another purpose.

	In the bad old days, performance was the number one priority because
computers were slow and resources were scarce -- if you didn't your code
wasn't usable. There is still a small amount of code where performance is
truly the most important priority. Certainly, very low-level kernel code
falls in this category.

	We aren't in the bad old days anymore. And there are quite a few things
that are important other than performance. Clear, simple code is easier to
understand and maintain and more likely to be correct. Modifications are
less likely to break hidden dependencies. Code that isn't heavily optimized
is more likely to be secure.

	And the supreme irony is that the code often performs better anyway! There
are a lot of reasons why this is often the case. For example, clearer more
modular code is easier to optimize algorithmically. Hand optimizations may
remain in code long past the point where they made sense and to the point
where they become pessimizations because of new CPU architectures or smarter
compilers. Poor code organization mixes performance-critical code with code
that's not performance-critical so that the critical code is harder to
identify and optimize.

	I am not saying that the use of C++ over C is likely to improve
performance. I'm saying that there's a lot of code where performance is not
the most important priority, and that this type of code accounts for the
majority of code in a monolithic kernel.

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-01 23:53                                         ` David Schwartz
@ 2006-05-02  5:12                                           ` Willy Tarreau
  2006-05-02 10:32                                             ` Avi Kivity
  2006-05-03 13:13                                           ` Mark Lord
  1 sibling, 1 reply; 200+ messages in thread
From: Willy Tarreau @ 2006-05-02  5:12 UTC (permalink / raw)
  To: David Schwartz; +Cc: Linux-Kernel@Vger. Kernel. Org

On Mon, May 01, 2006 at 04:53:47PM -0700, David Schwartz wrote:
> 
> > > The cost in developer time is borne once. The cost of performance
> > > is borne every time you run the application.
> 
> > The cost in developer time is borne every time someone needs to
> > modify the code.
> 
> 	Or understand the code. Or debug the code. Or verify that the code operates
> correctly. Or reuse the code for another purpose.
> 
> 	In the bad old days, performance was the number one priority because
> computers were slow and resources were scarce -- if you didn't your code
> wasn't usable. There is still a small amount of code where performance is
> truly the most important priority. Certainly, very low-level kernel code
> falls in this category.
> 
> 	We aren't in the bad old days anymore. And there are quite a few things
> that are important other than performance. Clear, simple code is easier to
> understand and maintain and more likely to be correct.

Sorry , but all the examples that have been given in C++ are clearly
unreadable and impossible to understand. I'd also like to note that
people were arguing about what the code was really doing, this means
that this language is absolutely not suited to such usages where you
want to know the exact behaviour. At least in C, this sort of thing
has never happened. People argue about what must be locked and important
things like this you'd never want the compiler to decide for you.

> Modifications are
> less likely to break hidden dependencies. Code that isn't heavily optimized
> is more likely to be secure.

To be secure, you first have to understand what the code precisely does,
not what it should do depending on how the compiler might optimise it.

> 	And the supreme irony is that the code often performs better anyway! There
> are a lot of reasons why this is often the case. For example, clearer more
> modular code is easier to optimize algorithmically. Hand optimizations may
> remain in code long past the point where they made sense and to the point
> where they become pessimizations because of new CPU architectures or smarter
> compilers. Poor code organization mixes performance-critical code with code
> that's not performance-critical so that the critical code is harder to
> identify and optimize.
> 
> 	I am not saying that the use of C++ over C is likely to improve
> performance. I'm saying that there's a lot of code where performance is not
> the most important priority, and that this type of code accounts for the
> majority of code in a monolithic kernel.

I'm still thinking that people who have problems understanding what the
code does want a level of abstraction between them and the CPU so that
the compiler thinks for them. I still don't see the *current* problem
you are trying to fix. Linux is written in C, as many other kernels and
it works. Nobody knows what it would become if rewritten in C++. Maybe
it will be better, maybe it would not run anymore on embedded systems,
maybe it would become fully buggy because nobody except a little bunch
of C++ coders would understand it... At least, I'm sure it will not be
the smart people who currently work on it.

Best of all, I'm even sure that people who are trying to push C++ in
the kernel would never ever write a line of code once it would be
accepted, because they don't seem to know what they're talking about
when it applies to kernel code.

> 	DS

Regards,
Willy


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02  5:12                                           ` Willy Tarreau
@ 2006-05-02 10:32                                             ` Avi Kivity
  2006-05-02 11:15                                               ` Martin Mares
                                                                 ` (2 more replies)
  0 siblings, 3 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 10:32 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: David Schwartz, Linux-Kernel@Vger. Kernel. Org

Willy Tarreau wrote:
> Sorry , but all the examples that have been given in C++ are clearly
> unreadable and impossible to understand.

If you don't know C++, sure.

Maybe this piece of code

  f [] = []
  f (x:xs) = f [y | y <- xs, y < x] ++ [x] ++ f [y | y <- xs, y > x]

Isn't very readable to a C or C++ coder, but it's meaning is instantly 
clear to one who knows the language it's written in. The equivalent C or 
C++ code is ~30 lines long and you might need a pen and paper to work 
out what it does.

>  I'd also like to note that
> people were arguing about what the code was really doing, this means
> that this language is absolutely not suited to such usages where you
> want to know the exact behaviour. 

Were they C coders or C++ coders?

> At least in C, this sort of thing
> has never happened. 

Like the recent prevent_tail_call() thing? Granted, C++ is a lot tricker 
than C. Much self-restraint is needed, and even then you can wind up 
where you didn't want to go.

> People argue about what must be locked and important
> things like this you'd never want the compiler to decide for you.
>
>   

No one suggests that C++ can decide what needs to be locked or not. To 
be sure, if there was a language where you could specify the locking 
rules in a central place (the class/struct declaration, for example) and 
let the compiler apply them, races and deadlocks would be much scarcer, 
and people could argue about what needs to be locked when the data 
structure is written, not every time it is used.

> To be secure, you first have to understand what the code precisely does,
> not what it should do depending on how the compiler might optimise it.
>   

If optimization changes your code's behaivor, your code is broken. 
People rely on the C++ optimizer for much the same things as C: to 
inline zero- or one- line functions and remove unused code. (There is 
just one exception in C++ where the optimizer _is_ allowed to modify 
behavior, but it is for an obviously correct scenario).

> I'm still thinking that people who have problems understanding what the
> code does want a level of abstraction between them and the CPU so that
> the compiler thinks for them.

No, they want not to repeat code and code patterns. It's the same 
motivation that lead to the invention of functions:

- functions allow you to reuse code instead of open-coding common sequences
- constructors/destructors allow you to reuse the do/undo (lock/unlock, 
etc.) pattern without writing it in full every time
- templates allow you to reuse code even when the data types change 
(like the preprocessor but not limited to linked lists)
- virtual functions allow you to dispatch a function based on the 
object's type, without writing the boilerplate casting
- exceptions allow you to do the detect error/undo partial 
modifications/propagate error thing without blowing up the code by a 
factor of five

It's just shorthand: but shorthand allows you to see what the code is 
doing instead of how it handles all the standard problems that occur 
again and again in programming.

The C people are content to stop at functions, but resist _all_ of the 
rest (it's okay to do some template-like magic with typeof, because it's 
still C, right?).

>  I still don't see the *current* problem
> you are trying to fix. Linux is written in C, as many other kernels and
> it works. Nobody knows what it would become if rewritten in C++. Maybe
> it will be better, maybe it would not run anymore on embedded systems,
> maybe it would become fully buggy because nobody except a little bunch
> of C++ coders would understand it... At least, I'm sure it will not be
> the smart people who currently work on it.
>   

Maybe it would be smaller, faster, more robust, and have even more 
flexible and fast-paced development.

Perhaps people who developed kernel-level code in _both_ C and C++ would 
be qualified to speculate on that (I have, but apparently I don't have a 
clue).

> Best of all, I'm even sure that people who are trying to push C++ in
> the kernel would never ever write a line of code once it would be
> accepted, because they don't seem to know what they're talking about
> when it applies to kernel code.
>   

Thanks.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 10:32                                             ` Avi Kivity
@ 2006-05-02 11:15                                               ` Martin Mares
  2006-05-02 11:26                                                 ` Avi Kivity
  2006-05-02 13:21                                               ` Willy Tarreau
  2006-05-02 13:34                                               ` Al Viro
  2 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-05-02 11:15 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Hello!

> Perhaps people who developed kernel-level code in _both_ C and C++ would 
> be qualified to speculate on that (I have, but apparently I don't have a 
> clue).

Well, what about just showing an example of kernel code in C++, which
you consider nice?

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
f u cn rd ths, u cn gt a gd jb n cmptr prgrmmng.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 11:15                                               ` Martin Mares
@ 2006-05-02 11:26                                                 ` Avi Kivity
  2006-05-02 11:40                                                   ` linux-os (Dick Johnson)
                                                                     ` (3 more replies)
  0 siblings, 4 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 11:26 UTC (permalink / raw)
  To: Martin Mares
  Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Martin Mares wrote:
> Hello!
>
>   
>> Perhaps people who developed kernel-level code in _both_ C and C++ would 
>> be qualified to speculate on that (I have, but apparently I don't have a 
>> clue).
>>     
>
> Well, what about just showing an example of kernel code in C++, which
> you consider nice?
>   

I don't have access to that code (which was closed source anyway).

But it executed C++ code within a few cycles of entering the reset 
vector (no standard BIOS), including but not limited to: programming the 
memory controller (430MX chipset), servicing interrupts, hardware 
accelerated 2D graphics (C&T 65550), IDE driver, simple filesystem, 
simple windowing GUI, network driver (Tulip) etc.

More recently I participated in writing a filesystem in C++. That's in 
userspace, but many of the techniques used in writing kernel code are 
necessary there (extreme robustness, can't assume infinite memory, 
locking, etc.)

There are C++ embedded kernels in http://www.zipworld.com.au/~akpm/ and 
http://ecos.sourceware.org/, but I haven't looked at them, so I can't 
say whether I consider them nice or not.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 11:26                                                 ` Avi Kivity
@ 2006-05-02 11:40                                                   ` linux-os (Dick Johnson)
  2006-05-02 12:42                                                   ` David Woodhouse
                                                                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ messages in thread
From: linux-os (Dick Johnson) @ 2006-05-02 11:40 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org


On Tue, 2 May 2006, Avi Kivity wrote:

> Martin Mares wrote:
>> Hello!
>>
>>
>>> Perhaps people who developed kernel-level code in _both_ C and C++ would
>>> be qualified to speculate on that (I have, but apparently I don't have a
>>> clue).
>>>
>>
>> Well, what about just showing an example of kernel code in C++, which
>> you consider nice?
>>
>
> I don't have access to that code (which was closed source anyway).
>
> But it executed C++ code within a few cycles of entering the reset
> vector (no standard BIOS), including but not limited to: programming the
> memory controller (430MX chipset), servicing interrupts, hardware
> accelerated 2D graphics (C&T 65550), IDE driver, simple filesystem,
> simple windowing GUI, network driver (Tulip) etc.
>

Oh wow! I'm impressed. You, know back in the '50s we did something
like that. It was a dynamic abacus for fast math. Since it's
proprietary, I can't disclose its exact nature. It's even used
by the CIA.

> More recently I participated in writing a filesystem in C++. That's in
> userspace, but many of the techniques used in writing kernel code are
> necessary there (extreme robustness, can't assume infinite memory,
> locking, etc.)

Sure, kernel code is probably written using symbols, too. It's a
lot like user-space as well.

>
> There are C++ embedded kernels in http://www.zipworld.com.au/~akpm/ and
> http://ecos.sourceware.org/, but I haven't looked at them, so I can't
> say whether I consider them nice or not.
>

While you are at it, look at:

http://www.google.com/search?hl=en&q=bullshit

> --
> error compiling committee.c: too many arguments to function
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.4 on an i686 machine (5592.89 BogoMips).
New book: http://www.lymanschool.com
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 11:26                                                 ` Avi Kivity
  2006-05-02 11:40                                                   ` linux-os (Dick Johnson)
@ 2006-05-02 12:42                                                   ` David Woodhouse
  2006-05-02 16:27                                                     ` Christer Weinigel
  2006-05-02 12:48                                                   ` Martin Mares
  2006-05-02 16:16                                                   ` Brian Beattie
  3 siblings, 1 reply; 200+ messages in thread
From: David Woodhouse @ 2006-05-02 12:42 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

On Tue, 2006-05-02 at 14:26 +0300, Avi Kivity wrote:
> There are C++ embedded kernels in http://www.zipworld.com.au/~akpm/
> and http://ecos.sourceware.org/, but I haven't looked at them, so I
> can't say whether I consider them nice or not. 

eCos is nice enough -- because it's mostly C :)

-- 
dwmw2


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 11:26                                                 ` Avi Kivity
  2006-05-02 11:40                                                   ` linux-os (Dick Johnson)
  2006-05-02 12:42                                                   ` David Woodhouse
@ 2006-05-02 12:48                                                   ` Martin Mares
  2006-05-02 13:52                                                     ` Avi Kivity
  2006-05-02 16:16                                                   ` Brian Beattie
  3 siblings, 1 reply; 200+ messages in thread
From: Martin Mares @ 2006-05-02 12:48 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Hello!

> But it executed C++ code within a few cycles of entering the reset 
> vector (no standard BIOS), including but not limited to: programming the 
> memory controller (430MX chipset), servicing interrupts, hardware 
> accelerated 2D graphics (C&T 65550), IDE driver, simple filesystem, 
> simple windowing GUI, network driver (Tulip) etc.

I really don't claim it's impossible to write kernels in C++ -- it's
clearly possible given that everything you can do in C, you can do in
C++ as well. But what I argued about is whether kernel programming in C++
can be easier and more efficient, which is why I wanted you to show
some examples. Real code speaks better than thousand theories.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Only dead fish swim with the stream.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 10:32                                             ` Avi Kivity
  2006-05-02 11:15                                               ` Martin Mares
@ 2006-05-02 13:21                                               ` Willy Tarreau
  2006-05-02 14:41                                                 ` Avi Kivity
  2006-05-02 13:34                                               ` Al Viro
  2 siblings, 1 reply; 200+ messages in thread
From: Willy Tarreau @ 2006-05-02 13:21 UTC (permalink / raw)
  To: Avi Kivity; +Cc: David Schwartz, Linux-Kernel@Vger. Kernel. Org

On Tue, May 02, 2006 at 01:32:05PM +0300, Avi Kivity wrote:
> Willy Tarreau wrote:
> >Sorry , but all the examples that have been given in C++ are clearly
> >unreadable and impossible to understand.
> 
> If you don't know C++, sure.
> 
> Maybe this piece of code
> 
>  f [] = []
>  f (x:xs) = f [y | y <- xs, y < x] ++ [x] ++ f [y | y <- xs, y > x]
> 
> Isn't very readable to a C or C++ coder, but it's meaning is instantly 
> clear to one who knows the language it's written in. The equivalent C or 
> C++ code is ~30 lines long and you might need a pen and paper to work 
> out what it does.

It would be the exact same problem I discribed above. If nobody understand
what it does, or if people need some deep thoughts to guess its behaviour,
the result will be negative. Currently, everyone can read the kernel code.
I was a terrible looser in C 11 years ago when I first looked at it, but I
did not need specific knowledge of implicit things that the kernel does to
understand what the code did, and to propose patches.

Right now, lots of newbies review the code and find bugs. If you write it
in a language such as above, it will quickly end up like the BSD kernels,
with a small very competent core team and lots of newbies around them.

> > I'd also like to note that
> >people were arguing about what the code was really doing, this means
> >that this language is absolutely not suited to such usages where you
> >want to know the exact behaviour. 
> 
> Were they C coders or C++ coders?

I don't know, what I can say is that they were people who regularly discuss
the kernel semantics on other threads. That's what matters. Those people are
good at finding kernel bugs and proposing interesting algorithms, it's a shame
that they had to discuss langage semantics on 5 lines of code !

> >At least in C, this sort of thing
> >has never happened. 
> 
> Like the recent prevent_tail_call() thing? Granted, C++ is a lot tricker 
> than C. Much self-restraint is needed, and even then you can wind up 
> where you didn't want to go.

I've not followed the issue, sorry.

> >People argue about what must be locked and important
> >things like this you'd never want the compiler to decide for you.
> >
> >  
> 
> No one suggests that C++ can decide what needs to be locked or not. To 
> be sure, if there was a language where you could specify the locking 
> rules in a central place (the class/struct declaration, for example) and 
> let the compiler apply them, races and deadlocks would be much scarcer, 
> and people could argue about what needs to be locked when the data 
> structure is written, not every time it is used.

I seems like pro-C++ people constantly tell the other ones "look, C++ can
code for you so that you won't have to worry about boring parts. Of coure,
if you need to know, you're still able to write is the old way". Since we
always want to know, I guess we'd use the C++ compiler (the slow one), with
pure-C code borrowing nothing from the C++ language. That would only be a
pure loss.

> >To be secure, you first have to understand what the code precisely does,
> >not what it should do depending on how the compiler might optimise it.
> >  
> 
> If optimization changes your code's behaivor, your code is broken. 
> People rely on the C++ optimizer for much the same things as C: to 
> inline zero- or one- line functions and remove unused code. (There is 
> just one exception in C++ where the optimizer _is_ allowed to modify 
> behavior, but it is for an obviously correct scenario).
> 
> >I'm still thinking that people who have problems understanding what the
> >code does want a level of abstraction between them and the CPU so that
> >the compiler thinks for them.
> 
> No, they want not to repeat code and code patterns. It's the same 
> motivation that lead to the invention of functions:
> 
> - functions allow you to reuse code instead of open-coding common 
> sequences
> - constructors/destructors allow you to reuse the do/undo (lock/unlock, 
> etc.) pattern without writing it in full every time
> - templates allow you to reuse code even when the data types change 
> (like the preprocessor but not limited to linked lists)
> - virtual functions allow you to dispatch a function based on the 
> object's type, without writing the boilerplate casting
> - exceptions allow you to do the detect error/undo partial 
> modifications/propagate error thing without blowing up the code by a 
> factor of five
> 
> It's just shorthand: but shorthand allows you to see what the code is 
> doing instead of how it handles all the standard problems that occur 
> again and again in programming.

I'm still not convinced. Every time I came across C++ code, it was an immense
unreadable crap (indentation, cAmEl case, "funny" operators which you have to
stop at because you need a few seconds of thought before confusing them with
others, etc...). Code that cannot be read at 3am. If you want a good example
of this, download and read p7zip. It does lots of magic^Wimplicit things which
quickly got me lost. I agree, I'm not a C++ developper. But many language are
slightly understandable to non-fellows, and this one looks really nasty.

You told us examples of programs you have written. If this is true, I have
a lot of respect for this, because it still seems impossible to me. I
understand they were closed source, but if you come across open source
kernel code that is readable by newbies, I think many people would be
interested to get a clue.

> The C people are content to stop at functions, but resist _all_ of the 
> rest (it's okay to do some template-like magic with typeof, because it's 
> still C, right?).
> 
> > I still don't see the *current* problem
> >you are trying to fix. Linux is written in C, as many other kernels and
> >it works. Nobody knows what it would become if rewritten in C++. Maybe
> >it will be better, maybe it would not run anymore on embedded systems,
> >maybe it would become fully buggy because nobody except a little bunch
> >of C++ coders would understand it... At least, I'm sure it will not be
> >the smart people who currently work on it.
> >  
> 
> Maybe it would be smaller, faster, more robust, and have even more 
> flexible and fast-paced development.
> 
> Perhaps people who developed kernel-level code in _both_ C and C++ would 
> be qualified to speculate on that (I have, but apparently I don't have a 
> clue).
> 
> >Best of all, I'm even sure that people who are trying to push C++ in
> >the kernel would never ever write a line of code once it would be
> >accepted, because they don't seem to know what they're talking about
> >when it applies to kernel code.
> >  
> 
> Thanks.

Regards,
Willy


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 10:32                                             ` Avi Kivity
  2006-05-02 11:15                                               ` Martin Mares
  2006-05-02 13:21                                               ` Willy Tarreau
@ 2006-05-02 13:34                                               ` Al Viro
  2006-05-02 14:02                                                 ` Avi Kivity
  2 siblings, 1 reply; 200+ messages in thread
From: Al Viro @ 2006-05-02 13:34 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

On Tue, May 02, 2006 at 01:32:05PM +0300, Avi Kivity wrote:
> Like the recent prevent_tail_call() thing? Granted, C++ is a lot tricker 
> than C. Much self-restraint is needed, and even then you can wind up 
> where you didn't want to go.

	Sigh...  You know, once upon a time there was a language called
Algol 68.  It had a _lot_ of expressive power and was fairly flexible -
both in type system and in syntax.  And it had been a fscking nightmare
for large projects.  Not because of lack of modularity - that part had
been all right.  The thing that kept killing large projects was different;
in effect, each group ended up with a language subset and developed a
discipline for it.  And as soon as they mixed, _especially_ if they were
close, but not quite the same, you had an ever-growing disaster.

	It's not easy to quantify; each language has dark corners and
there are more or less odd constructs specific to individual programmers
and to groups.  And yes, you certainly can write unreadable crap in any
language.  The question is, how many variants of "needed self-restraint"
are widespread, how well do they mix and how easy it is to recognize the
mismatches?  It's not a function of language per se, so it doesn't make
sense to compare C and C++ as languages in that respect.  However, C++
and C _styles_ can be compared and that's where C++ requires more force
to keep a large project away from becoming a clusterfsck.

	Sure, you need make sure that different groups of people use
more or less compatible styles anyway; it's just that with C++ you need
tighter control to get the same result.  And for kernel it's a killer.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 12:48                                                   ` Martin Mares
@ 2006-05-02 13:52                                                     ` Avi Kivity
  2006-05-02 14:13                                                       ` Al Viro
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 13:52 UTC (permalink / raw)
  To: Martin Mares
  Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Martin Mares wrote:
> Hello!
>
>   
>> But it executed C++ code within a few cycles of entering the reset 
>> vector (no standard BIOS), including but not limited to: programming the 
>> memory controller (430MX chipset), servicing interrupts, hardware 
>> accelerated 2D graphics (C&T 65550), IDE driver, simple filesystem, 
>> simple windowing GUI, network driver (Tulip) etc.
>>     
>
> I really don't claim it's impossible to write kernels in C++ -- it's
> clearly possible given that everything you can do in C, you can do in
> C++ as well. But what I argued about is whether kernel programming in C++
> can be easier and more efficient, which is why I wanted you to show
> some examples. Real code speaks better than thousand theories.
>
>   

Here are three versions of do_sendfile(). When you read it, please 
assume you know light_file_ptr as well as you know f{get,put}_light, etc.

The (IMO) improvement is not dramatic since this is fairly much straight line code.

static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
			   size_t count, loff_t max)
{
	struct file * in_file, * out_file;
	struct inode * in_inode, * out_inode;
	loff_t pos;
	ssize_t retval;
	int fput_needed_in, fput_needed_out;

	/*
	 * Get input file, and verify that it is ok..
	 */
	retval = -EBADF;
	in_file = fget_light(in_fd, &fput_needed_in);
	if (!in_file)
		goto out;
	if (!(in_file->f_mode & FMODE_READ))
		goto fput_in;
	retval = -EINVAL;
	in_inode = in_file->f_dentry->d_inode;
	if (!in_inode)
		goto fput_in;
	if (!in_file->f_op || !in_file->f_op->sendfile)
		goto fput_in;
	retval = -ESPIPE;
	if (!ppos)
		ppos = &in_file->f_pos;
	else
		if (!(in_file->f_mode & FMODE_PREAD))
			goto fput_in;
	retval = rw_verify_area(READ, in_file, ppos, count);
	if (retval < 0)
		goto fput_in;
	count = retval;

	retval = security_file_permission (in_file, MAY_READ);
	if (retval)
		goto fput_in;

	/*
	 * Get output file, and verify that it is ok..
	 */
	retval = -EBADF;
	out_file = fget_light(out_fd, &fput_needed_out);
	if (!out_file)
		goto fput_in;
	if (!(out_file->f_mode & FMODE_WRITE))
		goto fput_out;
	retval = -EINVAL;
	if (!out_file->f_op || !out_file->f_op->sendpage)
		goto fput_out;
	out_inode = out_file->f_dentry->d_inode;
	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
	if (retval < 0)
		goto fput_out;
	count = retval;

	retval = security_file_permission (out_file, MAY_WRITE);
	if (retval)
		goto fput_out;

	if (!max)
		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);

	pos = *ppos;
	retval = -EINVAL;
	if (unlikely(pos < 0))
		goto fput_out;
	if (unlikely(pos + count > max)) {
		retval = -EOVERFLOW;
		if (pos >= max)
			goto fput_out;
		count = max - pos;
	}

	retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);

	if (retval > 0) {
		current->rchar += retval;
		current->wchar += retval;
	}
	current->syscr++;
	current->syscw++;

	if (*ppos > max)
		retval = -EOVERFLOW;

fput_out:
	fput_light(out_file, fput_needed_out);
fput_in:
	fput_light(in_file, fput_needed_in);
out:
	return retval;
}



static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
			   size_t count, loff_t max)
{
	loff_t pos;
	ssize_t retval;

	/*
	 * Get input file, and verify that it is ok..
	 */
	light_file_ptr in_file(in_fd);
	if (!in_file.valid())
		return -EBADF;
	if (!in_file->readable())
		return -EBADF;
	retval = -EINVAL;
	struct inode *in_inode = in_file->dentry()->inode();
	if (!in_inode)
		return -EINVAL;
	// I'm assuming here that the default sendfile() returns -EINVAL
	if (!ppos)
		ppos = &in_file->f_pos;
	else
		if (!(in_file->mode() & FMODE_PREAD))
			return -ESPIPE;
	retval = rw_verify_area(READ, in_file, ppos, count);
	if (retval < 0)
		return retval;
	count = retval;

	retval = security_file_permission (in_file, MAY_READ);
	if (retval)
		return retval;

	/*
	 * Get output file, and verify that it is ok..
	 */
	light_file_ptr out_file(out_fd);
	if (!out_file)
		return -EBADF;
	if (!(out_file->writable())
		return -EBADF;
	// Again, assuming default sendpage returns -EINVAL
	struct inode *out_inode = out_file->dentry()->inode();
	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
	if (retval < 0)
		return retval;
	count = retval;

	retval = security_file_permission (out_file, MAY_WRITE);
	if (retval)
		return retval;

	if (!max)
		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);

	pos = *ppos;
	if (unlikely(pos < 0))
		return -EINVAL;
	if (unlikely(pos + count > max)) {
		if (pos >= max)
			return -EOVERFLOW;
		count = max - pos;
	}

	retval = in_file->sendfile(ppos, count, file_send_actor, out_file);

	if (retval > 0) {
		current->rchar += retval;
		current->wchar += retval;
	}
	current->syscr++;
	current->syscw++;

	if (*ppos > max)
		return -EOVERFLOW;

	return retval;
}

// now, with exceptions
static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
			   size_t count, loff_t max)
{
	loff_t pos;

	/*
	 * Get input file, and verify that it is ok..
	 */
	light_file_ptr in_file(in_fd);
	in_file->verify_readable();
	struct inode *in_inode = in_file->dentry()->inode();
	if (!in_inode)
		throw EINVAL;
	// I'm assuming here that the default sendfile() returns -EINVAL
	if (!ppos)
		ppos = &in_file->f_pos;
	else
        in_file->verify_preadable();
	count = in_file->verify_area(READ, ppos, count);

	in_file->security_verify_permission(MAY_READ);

	/*
	 * Get output file, and verify that it is ok..
	 */
	light_file_ptr out_file(out_fd);
	out_file->verify_writable();
	// Again, assuming default sendpage returns -EINVAL
	struct inode *out_inode = out_file->dentry()->inode();
	count = out_file->verify_area(WRITE, &out_file->f_pos, count);

	out_file->security_verify_permission(MAY_WRITE);

	if (!max)
		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);

	pos = *ppos;
	if (unlikely(pos < 0))
		throw EINVAL;
	if (unlikely(pos + count > max)) {
		if (pos >= max)
			throw EOVERFLOW;
		count = max - pos;
	}

	count = in_file->sendfile(ppos, count, file_send_actor, out_file);

	current->rchar += count;
	current->wchar += count;
	current->syscr++;
	current->syscw++;

	if (*ppos > max)
		throw EOVERFLOW;

	return count;
}


-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 13:34                                               ` Al Viro
@ 2006-05-02 14:02                                                 ` Avi Kivity
  2006-05-02 14:34                                                   ` Al Viro
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 14:02 UTC (permalink / raw)
  To: Al Viro; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Al Viro wrote:
> On Tue, May 02, 2006 at 01:32:05PM +0300, Avi Kivity wrote:
>   
>> Like the recent prevent_tail_call() thing? Granted, C++ is a lot tricker 
>> than C. Much self-restraint is needed, and even then you can wind up 
>> where you didn't want to go.
>>     
>
> 	Sigh...  You know, once upon a time there was a language called
> Algol 68.  It had a _lot_ of expressive power and was fairly flexible -
> both in type system and in syntax.  And it had been a fscking nightmare
> for large projects.  Not because of lack of modularity - that part had
> been all right.  The thing that kept killing large projects was different;
> in effect, each group ended up with a language subset and developed a
> discipline for it.  And as soon as they mixed, _especially_ if they were
> close, but not quite the same, you had an ever-growing disaster.
>
> 	It's not easy to quantify; each language has dark corners and
> there are more or less odd constructs specific to individual programmers
> and to groups.  And yes, you certainly can write unreadable crap in any
> language.  The question is, how many variants of "needed self-restraint"
> are widespread, how well do they mix and how easy it is to recognize the
> mismatches?  It's not a function of language per se, so it doesn't make
> sense to compare C and C++ as languages in that respect.  However, C++
> and C _styles_ can be compared and that's where C++ requires more force
> to keep a large project away from becoming a clusterfsck.
>
> 	Sure, you need make sure that different groups of people use
> more or less compatible styles anyway; it's just that with C++ you need
> tighter control to get the same result.  And for kernel it's a killer.
>   

Hey, I agree 100%, except for the last 6 words :) C++ is the very worst 
language I know in terms of badly thought out features, internal 
inconsistencies, ways to shoot one's feet off, and general ugliness. It 
will require _very_ tight control to avoid parts of the kernel going off 
in mutually incompatible directions.

But I think that the control is there; and if C++ is introduced slowly, 
one feature at a time, it can be kept sane. And I think there is 
definitely a payoff to be won out of a switch.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 13:52                                                     ` Avi Kivity
@ 2006-05-02 14:13                                                       ` Al Viro
  2006-05-02 14:54                                                         ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Al Viro @ 2006-05-02 14:13 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

On Tue, May 02, 2006 at 04:52:53PM +0300, Avi Kivity wrote:
> static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
> 			   size_t count, loff_t max)
> {
> 	loff_t pos;
> 	ssize_t retval;
> 
> 	/*
> 	 * Get input file, and verify that it is ok..
> 	 */
> 	light_file_ptr in_file(in_fd);

*snerk*
Good luck defining copying and conversion to file * for that puppy.  

> 	if (!in_file.valid())
> 		return -EBADF;
> 	if (!in_file->readable())
> 		return -EBADF;
> 	retval = -EINVAL;
> 	struct inode *in_inode = in_file->dentry()->inode();

Lovely.  Let's expose all fields as methods?

> 	if (!in_inode)
> 		return -EINVAL;

BTW, that can't happen.  Applies to the original as well.

> 	// I'm assuming here that the default sendfile() returns -EINVAL
> 	if (!ppos)
> 		ppos = &in_file->f_pos;
> 	else
> 		if (!(in_file->mode() & FMODE_PREAD))
> 			return -ESPIPE;

As opposed to ->readable() for checking FMODE_READ?

> 	light_file_ptr out_file(out_fd);
> 	if (!out_file)
> 		return -EBADF;

?

> 	if (!max)
> 		max = min(in_inode->i_sb->s_maxbytes, 
> 		out_inode->i_sb->s_maxbytes);

While we are at it, that's the only place where in_inode and out_inode
are used.  Also... how does one remember which of ->dentry, ->inode
and ->i_sb are methods and which are public fields?

> // now, with exceptions
> static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
> 			   size_t count, loff_t max)
> {
> 	loff_t pos;
> 
> 	/*
> 	 * Get input file, and verify that it is ok..
> 	 */
> 	light_file_ptr in_file(in_fd);
> 	in_file->verify_readable();

That assumes that error value returned in that case is the same everywhere.
It isn't.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 14:02                                                 ` Avi Kivity
@ 2006-05-02 14:34                                                   ` Al Viro
  2006-05-02 15:04                                                     ` Avi Kivity
  0 siblings, 1 reply; 200+ messages in thread
From: Al Viro @ 2006-05-02 14:34 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

On Tue, May 02, 2006 at 05:02:55PM +0300, Avi Kivity wrote:
> Hey, I agree 100%, except for the last 6 words :) C++ is the very worst 
> language I know in terms of badly thought out features, internal 
> inconsistencies, ways to shoot one's feet off, and general ugliness. It 
> will require _very_ tight control to avoid parts of the kernel going off 
> in mutually incompatible directions.
> 
> But I think that the control is there; and if C++ is introduced slowly, 
> one feature at a time, it can be kept sane. And I think there is 
> definitely a payoff to be won out of a switch.

You are far too optimistic.  In the best case it'll end up with higher
artificial entry barrier for contributors.  In the worst (and much more
realistic) the crap will leak all over the tree in addition to the
already present classes of bugs.

"Everyone has his pet subset/extension" is a killer for anything that isn't
done by 5-6 people, or, at least reviewed by 5-6 people who really can
read through _all_ incoming code.  For something like Linux kernel...
forget it.  It's far outside of the area where that would work.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 13:21                                               ` Willy Tarreau
@ 2006-05-02 14:41                                                 ` Avi Kivity
  2006-05-02 22:25                                                   ` Diego Calleja
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 14:41 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: David Schwartz, Linux-Kernel@Vger. Kernel. Org

Willy Tarreau wrote:
> It would be the exact same problem I discribed above. If nobody understand
> what it does, or if people need some deep thoughts to guess its behaviour,
> the result will be negative. Currently, everyone can read the kernel code.
> I was a terrible looser in C 11 years ago when I first looked at it, but I
> did not need specific knowledge of implicit things that the kernel does to
> understand what the code did, and to propose patches.
>
>   

11 years ago the kernel was _way_ simpler.

These days, you need to know that you can't call schedule() (or any 
function which may sleep -- why is that not implicit) within spin locks. 
You need to understand per-cpu variables, initcalls, rcu, memory 
barriers, reference counting, and lots of other "infrastructure" details 
that are engraved into your brain but not accessible to a newbie. Most 
of these (except perhaps reference counting) cannot be understood from 
looking at the code.

C++ allows you to add even more infrastructure, by providing support for 
patterns that can't be done in C. So yes, that adds more to the 
vocabulary you have to learn by heart but once you're over that the code 
is _more_ readable, more maintainable.

> Right now, lots of newbies review the code and find bugs. If you write it
> in a language such as above, it will quickly end up like the BSD kernels,
> with a small very competent core team and lots of newbies around them.
>
>   

C++ knowledge is now fairly widespread, I believe.

> I don't know, what I can say is that they were people who regularly discuss
> the kernel semantics on other threads. That's what matters. Those people are
> good at finding kernel bugs and proposing interesting algorithms, it's a shame
> that they had to discuss langage semantics on 5 lines of code !
>   

I'm sorry to have wasted their time. But surely you understand these 
things once and then move on? Like when someone proposes a new function 
to replace repeated code, there's argument about it's name, coding 
style, and hopefully about the content. The people replace the 
open-coded sequence with the new function.

It's the same here at a slightly higher level. You argue what s spinlock 
guard should look like, whether it's optimal or not, and then you can 
use it where applicable and avoid those gotos or code duplications for 
error cases.

 

>
> I seems like pro-C++ people constantly tell the other ones "look, C++ can
> code for you so that you won't have to worry about boring parts. Of coure,
> if you need to know, you're still able to write is the old way". Since we
> always want to know, I guess we'd use the C++ compiler (the slow one), with
> pure-C code borrowing nothing from the C++ language. That would only be a
> pure loss.
>   

It's not "if you need to know", it's "if you want to break the rules".

For example, the spinlock guard thingie allows you to say, "please 
spin_unlock this spinlock for me, whichever way I return from this 
function". There is no knowledge taken away, you know exactly what it 
will do and when; only the code is made clearer.

But if you want the function to lock but not unlock, or do the 
atomic_dec_and_lock() thing, or do lock reordering to avoid ABBA 
deadlocks, or whatever, the primitives are still there.

These constructs allow you to make simple things simple (and automatic) 
but don't take away the complex things.

(example, for context:

{
    spinlock_guard guard(some_lock);
    if (x)
        return -ESOMETHING;
    blah();
    return 0;
}   

there is nothing implicit once you know spinlock_guard)


>> No, they want not to repeat code and code patterns. It's the same 
>> motivation that lead to the invention of functions:
>>
>> - functions allow you to reuse code instead of open-coding common 
>> sequences
>> - constructors/destructors allow you to reuse the do/undo (lock/unlock, 
>> etc.) pattern without writing it in full every time
>> - templates allow you to reuse code even when the data types change 
>> (like the preprocessor but not limited to linked lists)
>> - virtual functions allow you to dispatch a function based on the 
>> object's type, without writing the boilerplate casting
>> - exceptions allow you to do the detect error/undo partial 
>> modifications/propagate error thing without blowing up the code by a 
>> factor of five
>>
>> It's just shorthand: but shorthand allows you to see what the code is 
>> doing instead of how it handles all the standard problems that occur 
>> again and again in programming.
>>     
>
> I'm still not convinced. Every time I came across C++ code, it was an immense
> unreadable crap (indentation, cAmEl case, "funny" operators which you have to
> stop at because you need a few seconds of thought before confusing them with
> others, etc...). Code that cannot be read at 3am. If you want a good example
> of this, download and read p7zip. It does lots of magic^Wimplicit things which
> quickly got me lost. I agree, I'm not a C++ developper. But many language are
> slightly understandable to non-fellows, and this one looks really nasty.
>   

I agree - I've seen it done many times. C++ has the potential for a lot 
of nastiness, and what is more, it seems to bring out the worst in 
people. We would definitely need an Al Viro for C++ if the kernel were 
to be ported.

I've yet to find a language that combines low level access, efficiency, 
cleanliness, and expressive power.

> You told us examples of programs you have written. If this is true, I have
> a lot of respect for this, because it still seems impossible to me. I
> understand they were closed source, but if you come across open source
> kernel code that is readable by newbies, I think many people would be
> interested to get a clue.
>   

I posted an example of do_sendfile() as it might be incrementally converted.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 14:13                                                       ` Al Viro
@ 2006-05-02 14:54                                                         ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 14:54 UTC (permalink / raw)
  To: Al Viro
  Cc: Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

Al Viro wrote:
> On Tue, May 02, 2006 at 04:52:53PM +0300, Avi Kivity wrote:
>   
>> static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
>> 			   size_t count, loff_t max)
>> {
>> 	loff_t pos;
>> 	ssize_t retval;
>>
>> 	/*
>> 	 * Get input file, and verify that it is ok..
>> 	 */
>> 	light_file_ptr in_file(in_fd);
>>     
>
> *snerk*
> Good luck defining copying and conversion to file * for that puppy.  
>
>   

class light_file_ptr {
public:
    explicit light_file_ptr(int fd)
    {
        _file = fget_light(fd, &_fput_needed);
    }
    ~light_file_ptr()
    {
        fput_light(_file, _fput_needed);
    }
    bool valid() const
    {
        return _file != 0;
    }
    struct file *operator->() // allowed for libs :)
    {
        return _file;
    }
private:
    struct file *_file;
    int _fput_needed;
};


>> 	struct inode *in_inode = in_file->dentry()->inode();
>>     
>
> Lovely.  Let's expose all fields as methods?
>
>   

If you like. I won't insist.

>> 	if (!in_inode)
>> 		return -EINVAL;
>>     
>
> BTW, that can't happen.  Applies to the original as well.
>
>   

I believe this bug is more visible when there is less code in the function.

>> 	// I'm assuming here that the default sendfile() returns -EINVAL
>> 	if (!ppos)
>> 		ppos = &in_file->f_pos;
>> 	else
>> 		if (!(in_file->mode() & FMODE_PREAD))
>> 			return -ESPIPE;
>>     
>
> As opposed to ->readable() for checking FMODE_READ?
>
>   

Forgot, sorry. I'll redo the patch.

>> 	light_file_ptr out_file(out_fd);
>> 	if (!out_file)
>> 		return -EBADF;
>>     
>
> ?
>   

Sorry, !out_file.valid().

>> 	if (!max)
>> 		max = min(in_inode->i_sb->s_maxbytes, 
>> 		out_inode->i_sb->s_maxbytes);
>>     
>
> While we are at it, that's the only place where in_inode and out_inode
> are used.  Also... how does one remember which of ->dentry, ->inode
> and ->i_sb are methods and which are public fields?
>   

I usually make all publics either methods (a class) or fields (a struct).


>> // now, with exceptions
>> static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
>> 			   size_t count, loff_t max)
>> {
>> 	loff_t pos;
>>
>> 	/*
>> 	 * Get input file, and verify that it is ok..
>> 	 */
>> 	light_file_ptr in_file(in_fd);
>> 	in_file->verify_readable();
>>     
>
> That assumes that error value returned in that case is the same everywhere.
> It isn't.
>   

Okay, in_file->verify_readable(EBADF); Yuck.

Thanks for the review.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 14:34                                                   ` Al Viro
@ 2006-05-02 15:04                                                     ` Avi Kivity
  2006-05-02 15:15                                                       ` Al Viro
  0 siblings, 1 reply; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 15:04 UTC (permalink / raw)
  To: Al Viro; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Al Viro wrote:
> On Tue, May 02, 2006 at 05:02:55PM +0300, Avi Kivity wrote:
>   
>> Hey, I agree 100%, except for the last 6 words :) C++ is the very worst 
>> language I know in terms of badly thought out features, internal 
>> inconsistencies, ways to shoot one's feet off, and general ugliness. It 
>> will require _very_ tight control to avoid parts of the kernel going off 
>> in mutually incompatible directions.
>>
>> But I think that the control is there; and if C++ is introduced slowly, 
>> one feature at a time, it can be kept sane. And I think there is 
>> definitely a payoff to be won out of a switch.
>>     
>
> You are far too optimistic.  In the best case it'll end up with higher
> artificial entry barrier for contributors.  In the worst (and much more
> realistic) the crap will leak all over the tree in addition to the
> already present classes of bugs.
>
> "Everyone has his pet subset/extension" is a killer for anything that isn't
> done by 5-6 people, or, at least reviewed by 5-6 people who really can
> read through _all_ incoming code.  For something like Linux kernel...
> forget it.  It's far outside of the area where that would work.
>   
If it has 'template' or 'operator' in it, make sure some sane people 
look at it.

IIRC, when the gcc people discussed this, they raised the possibility of 
adding compiler switches to allow subsetting the language. But there's 
nothing real out there that I know of.

BTW, C++ could take over some of sparse's function:

int foo(user_ptr<struct fugly_ioctl_arg> arg)
{
    return bar(arg->field); // won't compile
    struct fugly_ioctl_arg s;
    if (arg->copy_from_user(&s))
        return -EFAULT;
    return bar(&s); // yes!
}

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:04                                                     ` Avi Kivity
@ 2006-05-02 15:15                                                       ` Al Viro
  2006-05-02 15:19                                                         ` Avi Kivity
  2006-05-02 15:24                                                         ` Kyle Moffett
  0 siblings, 2 replies; 200+ messages in thread
From: Al Viro @ 2006-05-02 15:15 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

On Tue, May 02, 2006 at 06:04:23PM +0300, Avi Kivity wrote:
> BTW, C++ could take over some of sparse's function:

And the point of that would be?  sparse is _fast_ and easy to modify;
g++ is neither.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:15                                                       ` Al Viro
@ 2006-05-02 15:19                                                         ` Avi Kivity
  2006-05-02 15:27                                                           ` Kyle Moffett
  2006-05-02 15:28                                                           ` Al Viro
  2006-05-02 15:24                                                         ` Kyle Moffett
  1 sibling, 2 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 15:19 UTC (permalink / raw)
  To: Al Viro; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Al Viro wrote:
> On Tue, May 02, 2006 at 06:04:23PM +0300, Avi Kivity wrote:
>   
>> BTW, C++ could take over some of sparse's function:
>>     
>
> And the point of that would be?  sparse is _fast_ and easy to modify;
> g++ is neither.
>   

I wasn't talking about modifying gcc to do the checking, rather using 
language features so that the checks would happen during a regular 
compile. That would mean we weren't dependent on somebody running sparse 
with a configuration that triggers the bug, but those few who compile 
the code before submitting the patch would get it automatically checked.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:15                                                       ` Al Viro
  2006-05-02 15:19                                                         ` Avi Kivity
@ 2006-05-02 15:24                                                         ` Kyle Moffett
  1 sibling, 0 replies; 200+ messages in thread
From: Kyle Moffett @ 2006-05-02 15:24 UTC (permalink / raw)
  To: Al Viro
  Cc: Avi Kivity, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

On May 2, 2006, at 11:15:25, Al Viro wrote:
> On Tue, May 02, 2006 at 06:04:23PM +0300, Avi Kivity wrote:
>> BTW, C++ could take over some of sparse's function:
>
> And the point of that would be?  sparse is _fast_ and easy to  
> modify; g++ is neither.

For example; you can run _both_ a full sparse with all checks _and_  
"gcc -Wall -Wextra -Werror -g -O2" in less time than it takes to  
_just_ run "g++ -O0" on a nearly identical file.  If you have some  
new typechecking to do, figure out how to add it to sparse without  
cluttering up the syntax, don't convert the thing to C++, slow down  
the compile, etc.

Cheers,
Kyle Moffett



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:19                                                         ` Avi Kivity
@ 2006-05-02 15:27                                                           ` Kyle Moffett
  2006-05-02 15:30                                                             ` Avi Kivity
  2006-05-02 15:28                                                           ` Al Viro
  1 sibling, 1 reply; 200+ messages in thread
From: Kyle Moffett @ 2006-05-02 15:27 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Al Viro, Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

On May 2, 2006, at 11:19:35, Avi Kivity wrote:
> I wasn't talking about modifying gcc to do the checking, rather  
> using language features so that the checks would happen during a  
> regular compile. That would mean we weren't dependent on somebody  
> running sparse with a configuration that triggers the bug, but  
> those few who compile the code before submitting the patch would  
> get it automatically checked.

There's a reason that we tell all patch submitters to run "make C=1"  
on several configs before submitting patches.  Besides, you seem to  
have a vast misunderstanding of LK development processes; we frown  
heavily on people who don't "compile their code before submitting the  
patch", it's not a rare thing at all.

Cheers,
Kyle Moffett

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:19                                                         ` Avi Kivity
  2006-05-02 15:27                                                           ` Kyle Moffett
@ 2006-05-02 15:28                                                           ` Al Viro
  2006-05-02 15:51                                                             ` Avi Kivity
  1 sibling, 1 reply; 200+ messages in thread
From: Al Viro @ 2006-05-02 15:28 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

On Tue, May 02, 2006 at 06:19:35PM +0300, Avi Kivity wrote:
> Al Viro wrote:
> >On Tue, May 02, 2006 at 06:04:23PM +0300, Avi Kivity wrote:
> >  
> >>BTW, C++ could take over some of sparse's function:
> >>    
> >
> >And the point of that would be?  sparse is _fast_ and easy to modify;
> >g++ is neither.
> >  
> 
> I wasn't talking about modifying gcc to do the checking, rather using 
> language features so that the checks would happen during a regular 
> compile. That would mean we weren't dependent on somebody running sparse 
> with a configuration that triggers the bug, but those few who compile 
> the code before submitting the patch would get it automatically checked.

g++ won't cover all checks sparse is capable of, so you still want to
run the latter over new code anyway (== pass C=1 to make).  IOW, type
safety from C++ isn't particulary good argument.

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:27                                                           ` Kyle Moffett
@ 2006-05-02 15:30                                                             ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 15:30 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: Al Viro, Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Kyle Moffett wrote:
> On May 2, 2006, at 11:19:35, Avi Kivity wrote:
>> I wasn't talking about modifying gcc to do the checking, rather using 
>> language features so that the checks would happen during a regular 
>> compile. That would mean we weren't dependent on somebody running 
>> sparse with a configuration that triggers the bug, but those few who 
>> compile the code before submitting the patch would get it 
>> automatically checked.
>
> There's a reason that we tell all patch submitters to run "make C=1" 
> on several configs before submitting patches.  Besides, you seem to 
> have a vast misunderstanding of LK development processes; we frown 
> heavily on people who don't "compile their code before submitting the 
> patch", it's not a rare thing at all.
>

That was tongue in cheek. Perhaps I should have added a smiley.

I follow lkml quite closely, even though I lack the time to contribute 
in the areas that interest me.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 15:28                                                           ` Al Viro
@ 2006-05-02 15:51                                                             ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 15:51 UTC (permalink / raw)
  To: Al Viro; +Cc: Willy Tarreau, David Schwartz, Linux-Kernel@Vger. Kernel. Org

Al Viro wrote:
> g++ won't cover all checks sparse is capable of, so you still want to
> run the latter over new code anyway (== pass C=1 to make).  IOW, type
> safety from C++ isn't particulary good argument.
>   
I'm pretty sure that sparse can't validate all the casting from void 
pointers and from "base classes". Nor can it find bugs in data 
structures which are open-coded instead of template libraries. Do 
correct me if I'm wrong.

I'm not familiar with sparse's capabilities beyond __user, locking 
depth, and the like (pulling it now). Can you point me to any information?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-27 22:55               ` Bill Davidsen
@ 2006-05-02 15:58                 ` Randy.Dunlap
  2006-05-02 20:36                 ` David Schwartz
  1 sibling, 0 replies; 200+ messages in thread
From: Randy.Dunlap @ 2006-05-02 15:58 UTC (permalink / raw)
  To: Bill Davidsen; +Cc: linux-os, alan, linux-kernel

On Thu, 27 Apr 2006 18:55:02 -0400 Bill Davidsen wrote:

> linux-os (Dick Johnson) wrote:
> > On Mon, 24 Apr 2006, J.A. Magallon wrote:

> 
> If you hadn't made this next point I would have...
> > 
> > But, a master carpenter has many tools. He chooses the best for each
> > task. When you need to make computer hardware do what you want, in
> > a defined manner, in the particular order in which you require,
> > you use assembly language to generate the exact machine-code required.
> > It is possible to compromise a bit and use a slightly higher-level
> > procedural language called C. One loses control of everything with
> > any other language. Note that before C was invented, all operating
> > system code was written in assembly.
> 
> Hate to tell you, C came about a decade after MULTICS was written in 
> PL/1, and I think DEC had VMS out in BLISS before C. C came from B (as 
> did IMP68), which came from BCPL.

and Burroughs used Algol for multi-proc (master/slave, not SMP)
virtual memory OSes in the 1960s.  :)

---
~Randy

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 11:26                                                 ` Avi Kivity
                                                                     ` (2 preceding siblings ...)
  2006-05-02 12:48                                                   ` Martin Mares
@ 2006-05-02 16:16                                                   ` Brian Beattie
  2006-05-02 16:21                                                     ` Avi Kivity
  3 siblings, 1 reply; 200+ messages in thread
From: Brian Beattie @ 2006-05-02 16:16 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

On Tue, 2006-05-02 at 14:26 +0300, Avi Kivity wrote:

> 
> There are C++ embedded kernels in http://www.zipworld.com.au/~akpm/ and 
> http://ecos.sourceware.org/, but I haven't looked at them, so I can't 
> say whether I consider them nice or not.

You keep saying the eCos is written in C++, I see no evidence of that.

> 
-- 
Brian Beattie
Firmware Engineer
APCON, Inc.
BrianB@apcon.com


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 16:16                                                   ` Brian Beattie
@ 2006-05-02 16:21                                                     ` Avi Kivity
  0 siblings, 0 replies; 200+ messages in thread
From: Avi Kivity @ 2006-05-02 16:21 UTC (permalink / raw)
  To: Brian Beattie
  Cc: Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

Brian Beattie wrote:
> On Tue, 2006-05-02 at 14:26 +0300, Avi Kivity wrote:
>
>   
>> There are C++ embedded kernels in http://www.zipworld.com.au/~akpm/ and 
>> http://ecos.sourceware.org/, but I haven't looked at them, so I can't 
>> say whether I consider them nice or not.
>>     
>
> You keep saying the eCos is written in C++, I see no evidence of that.
>   

Someone posted in on this thread; I have no prior experience with it.

However, this may satisfy you:

http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/kernel/current/src/sched/sched.cxx?rev=1.18&content-type=text/x-cvsweb-markup&cvsroot=ecos

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 12:42                                                   ` David Woodhouse
@ 2006-05-02 16:27                                                     ` Christer Weinigel
  0 siblings, 0 replies; 200+ messages in thread
From: Christer Weinigel @ 2006-05-02 16:27 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Avi Kivity, Martin Mares, Willy Tarreau, David Schwartz,
	Linux-Kernel@Vger. Kernel. Org

David Woodhouse <dwmw2@infradead.org> writes:

> On Tue, 2006-05-02 at 14:26 +0300, Avi Kivity wrote:
> > There are C++ embedded kernels in http://www.zipworld.com.au/~akpm/
> > and http://ecos.sourceware.org/, but I haven't looked at them, so I
> > can't say whether I consider them nice or not. 
> 
> eCos is nice enough -- because it's mostly C :)

And those parts that are C++ (from a 2 year old eCos dist) won't
compile with a modern g++.  I tried to compile RedBoot on a Fedora
Core 5 system and it was a very painful experience, old deprecated C++
code was breaking all over the place.  It may just have been the the
eCos configuration tool (which I belive is written in C++) that failed
to compile, but anyway, I had to use an older version of g++ and some
flag to make the old broken C++ code generate warnings, not errors.

  /Christer

-- 
"Just how much can I get away with and still go to heaven?"

Freelance consultant specializing in device driver programming for Linux 
Christer Weinigel <christer@weinigel.se>  http://www.weinigel.se

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback + sparse
  2006-04-26 20:44                       ` Randy.Dunlap
@ 2006-05-02 20:09                         ` Randy.Dunlap
  0 siblings, 0 replies; 200+ messages in thread
From: Randy.Dunlap @ 2006-05-02 20:09 UTC (permalink / raw)
  To: linux-sparse; +Cc: xavier.bestel, davids, linux-kernel

On Wed, 26 Apr 2006 13:44:19 -0700 Randy.Dunlap wrote:

> > > 	C++ has how many additional reserved words? I believe the list is delete,
> > > friend, private, protected, public, template, throw, try, and catch.
> > 
> > You forgot namespace, mutable, new, class, const_cast, dynamic_cast,
> > static_cast, reinterpret_cast, explicit, true, false, operator, typeid,
> > typename and virtual. Maybe I forgot some (interface ?). Probably some
> > new ones will appear.
> 
> I did a sparse patch to check for all(?) of those once (with Linus's
> help).  I don't know if it still applies or not...
> 
> It's at http://www.xenotime.net/linux/sparse/check_keywords_v7.patch
> (You'll also need the other patch there; they got a bit comingled:
> http://www.xenotime.net/linux/sparse/check_sizeof_v7.patch)

I updated this patch so that it works with sparse (snapshot of
2006-may-01).  The patch is here:
http://www.xenotime.net/linux/sparse/sparse-keywords-sizes.patch


sparse additions to:
- check for C/C++ keywords: usage: -keywords
- print all global data symbols and their sizes: usage: -list-symbols
  Example of -list-symbols:
  make C=2 CF="-list-symbols" arch/x86_64/kernel/smpboot.o
  arch/x86_64/kernel/smpboot.c:90:20: struct cpuinfo_x86 [addressable] [toplevel
] [assigned] cpu_data[8]: compound size 1344, alignment 64

---
~Randy

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: C++ pushback
  2006-04-27 22:55               ` Bill Davidsen
  2006-05-02 15:58                 ` Randy.Dunlap
@ 2006-05-02 20:36                 ` David Schwartz
  1 sibling, 0 replies; 200+ messages in thread
From: David Schwartz @ 2006-05-02 20:36 UTC (permalink / raw)
  To: Linux-Kernel@Vger. Kernel. Org


> C++ allows more abstraction than C, unfortunately too many people go
> right past past abstraction to obfuscation. With operator overloading
> it's possible to generate write-only code, and programs where "A=B+C"
> does file operations :-( That doesn't belong in an operating system, C
> is the right choice.

>     -bill davidsen (davidsen@tmr.com)

	I reject any argument of the type "because a language *allows* you to do X,
and X is not always good, the language is bad". Now, if the language
*required* you to do bad things, that would be a different story.

	If I could demonstrate ways to do bad things in C that don't belong in an
operating system, would that convince you that C is not the right choice?
For example, C allows easy use of floating point math, which doesn't belong
in an operating system either.

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 14:41                                                 ` Avi Kivity
@ 2006-05-02 22:25                                                   ` Diego Calleja
  0 siblings, 0 replies; 200+ messages in thread
From: Diego Calleja @ 2006-05-02 22:25 UTC (permalink / raw)
  To: Avi Kivity; +Cc: willy, davids, linux-kernel

El Tue, 02 May 2006 17:41:15 +0300,
Avi Kivity <avi@argo.co.il> escribió:

> I've yet to find a language that combines low level access, efficiency, 
> cleanliness, and expressive power.

In case someone is interested, the freebsd people is trying to design
something that tries to achieve such things for the particular case
of the kernel without falling in the dangers of c++ 

"...a dialect of the C language that simplifies the task of writing kernel
code. It should include language extensions that make it possible to write
kernel code more cleanly and with less bugs. An example of this would have
language support for linked lists, to obviate the need for messy MACROs"

http://wikitest.freebsd.org/moin.cgi/K

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-01 23:53                                         ` David Schwartz
  2006-05-02  5:12                                           ` Willy Tarreau
@ 2006-05-03 13:13                                           ` Mark Lord
  2006-05-03 20:51                                             ` David Schwartz
  1 sibling, 1 reply; 200+ messages in thread
From: Mark Lord @ 2006-05-03 13:13 UTC (permalink / raw)
  To: davids; +Cc: Linux-Kernel@Vger. Kernel. Org

>In the bad old days, performance was the number one priority because
> computers were slow and resources were scarce

And that is still *very much* the case on huge numbers of systems
running Linux --> Embedded systems <---

Cheers

^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: Compiling C++ modules
  2006-05-03 13:13                                           ` Mark Lord
@ 2006-05-03 20:51                                             ` David Schwartz
  0 siblings, 0 replies; 200+ messages in thread
From: David Schwartz @ 2006-05-03 20:51 UTC (permalink / raw)
  To: Linux-Kernel@Vger. Kernel. Org


> >In the bad old days, performance was the number one priority because
> >computers were slow and resources were scarce

> And that is still *very much* the case on huge numbers of systems
> running Linux --> Embedded systems <---

	Yes and no. Any embedded system likely to run a full Linux kernel today has
at least ten times the performance and resources of the computers from the
bad old days.

	The majority of embedded systems that run very low-end hardware perform
tasks where performance is not particularly important anyway (microwave
oven, elevator). Those that perform more sophisticated tasks generally have
correspondingly more impressive hardware.

	In my experience, reliability is much more important than performance in
most embedded systems. If C++ results in cleaner and better organized code,
for some particular piece of code, it would be madness to choose C out of
fear that C++ will perform worse. (Of course, that's a big 'if'.)

	In fact, in all the years I developed embedded systems (from industrial
knitting machine controllers to medical devices) I can't remember a single
project where performance was the number one priority, or even a
particularly high one. Feature set, reliability, development cost and time,
ease of use, and the like were typically way ahead of performance. Perhaps
for a router or something like that it would be different. But I do not
believe that embedded systems in general are a class where performance is
more important than elsewhere.

	There are small embedded operating systems that are written primarily in
C++.

	DS



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: C++ pushback
  2006-04-25  7:33       ` Avi Kivity
  2006-04-25  7:47         ` Nick Piggin
@ 2006-05-13 16:21         ` Esben Nielsen
  1 sibling, 0 replies; 200+ messages in thread
From: Esben Nielsen @ 2006-05-13 16:21 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Martin Mares, linux-kernel



On Tue, 25 Apr 2006, Avi Kivity wrote:

> [...]
> Haskell is an excellent language, but it is not a system programming
> language. Kernel programming does not fit well into the functional model.

I find it really funny you say that. I have been thinking about what
language would be the most suitable for writing a kernel in and I find
that _functional_  languages ought to do the trick.

The essential thing about functional languages is that they use copy on
write. You never modify a piece of memory but make new copy with the
changes. Doesn't that remind you of RCU? Yes, you don't need locks! This
is essential when dealing with the future computers which will have lots
of CPU cores. Ofcourse, when accessing a piece of hardware you can't take
a copy and you would need a lock around the hardware access.
And ofcourse, you will need to make a small runtime system with
garbage-collection. The choice there would be C. So the kernel would
consist of assembler, C and an almost functional language like OCaml.
The strong typing and the lack of pointer arithmetic would also silence
any talks about microkernels.

But dreaming asside and back to the real world and the original thread:

I have experience with C and C++ at the system level and I do a little
Linux kernel hacking as a hobby. I want to push Linux in the embedded
system area because even the very high end RTOS we use at work sucks in
many ways.
But although that RTOS is written in C, it does have the ability to load
modules written in C++.  It doesn't have any userspace so every
application is loaded  directly into the kernel - and applications
are very often written in C++.

I think one ought to be able to write kernel modules in C++ as well. Many
companies now running their own home-made "OS"  - typically written in
assambler and C++ - are considering switching to  Linux. One of the
tumbling blocks is that they can not reuse their drivers as they would
have to be ported _back_ to C. A lot of people find that redicoulus and would
findanother OS just because of that. Remember that many, many people out there
think that when you say "C", you really mean C++. For them old flat C is
simply not existing anymore.

Now I don't think the main line kernel tree should include modules written
in C++. I have in the past "converted" a mud from being compiled with gcc
to being compiled with g++. It worked fine for me but after that it was
much harder for others to participate in the project. I wouldn't admit it
at that time; but now I see that it could very well have raised the level
of entry by a lot. C++ is simply very _hard_ to learn.

That said I have a lot of fun coding C++ at work. Many companies use
C++ because you really are more productive than in C. (Another reason is
that in the Windows world code generators like flex, rpcgen etc. are frowned
upon as they are not "standeard" and are hard to fit into build
environment. Therefore terrible stuff like Spirit is invented.
C++  hackers want to do everything within C++ and can't imagine writing
scripts and small code generators for generating all the trivial C code.
That latter often gives a better result, too, because you can only do 95%
with templates.)

But I find C++ basicly broken. It wants to be both high and lowlevel.
It doesn't have garbage collection; but it is almost impossible to make
the semi-manual memory management work 100%. It works 99.9% so it is
acceptable for most uses but not in a OS kernel.

And like Lisp wants to do with macros, C++ wants to make the coder create
his own syntax with operator overloading and templates. That often makes
the code totally unreadable for the causual reader. C++ encourages programmers
to do this stuff but 90% of the time it is done, it shouldn't have been
done. A language feature which is abused 90% of the time is bad no matter
what beautifull things can be done with it.
It is fine that you sort of can make your own "language" for your specific
perpose, but it is a huge mistake to mix the language definitions with the
actual program. It ought to be layered, so you first take your basic
compiler, make your extentions/modifications and then use that compiler on
your program. Then those modifications can be well thought over before
being applied.

And like in all OO languages you need a complete UML diagram before you can
read the code. In C I can usually find what I am looking for in even large
projects like Linux with just grep and less; but for OO languages you need
tools which can actually parse and understand the code to help you find
the relevvant functions/methods for you. grep can simply not do it because
a lot of functions/methods have identical names.

I understand why people are using C++, but I think it is a dead end. Stay
with C or go to a true highlevel language. Even Microsoft have figured
that out now; but because they have pushed C++ for years a lot of people
use C++ today without even thinking it is possible to use plain C - or
anything else. I think it is worth for the Linux community to meet them half
way and make it possible to compile C++ modules to the kernel, but
disallow actual C++ in the official kernel tree.

This his is how the RTOS I mentioned supports C++ modules by the way:

All public headers are wrapped with

#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif

and no C++ keywords are used. No inline functions are present so no
actual code from the header files have to be compiled with the C++
compiler.

To initialize global and static constructors first the module is compiled
into a tmp.o. This is now searched for such constructors using nm. A
function which calls them all is now generated in a auto.c.
The final module is tmp.o and auto.o combined. The OS simply calls the
generated function if the module has successfully been linked.

Merging a patch fixing the header files and modifying modpost to also call
constructors wouldn't destroy anything for the Linux kernel and make it
possible to make C++ modules as long as one avoids exceptions.

Doing exceptions in the kernel would be much harder but doable - but it
might make a runtime overhead which isn't acceptable. But maybe a config
option enabling them could be tolerated.


Esben



^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 18:21 Al Boldi
  2006-05-02 20:28 ` J.A. Magallon
  2006-05-02 23:55 ` Peter Williams
@ 2006-05-03  8:09 ` Steven Rostedt
  2 siblings, 0 replies; 200+ messages in thread
From: Steven Rostedt @ 2006-05-03  8:09 UTC (permalink / raw)
  To: Al Boldi; +Cc: Christer Weinigel, linux-kernel



On Tue, 2 May 2006, Al Boldi wrote:

> > --
> > "Just how much can I get away with and still go to heaven?"
>
> Just know that HE is one and only one.
>

Who's "HE"?  Linus?  ;-)

-- Steve


^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 18:21 Al Boldi
  2006-05-02 20:28 ` J.A. Magallon
@ 2006-05-02 23:55 ` Peter Williams
  2006-05-03  8:09 ` Steven Rostedt
  2 siblings, 0 replies; 200+ messages in thread
From: Peter Williams @ 2006-05-02 23:55 UTC (permalink / raw)
  To: Al Boldi; +Cc: Christer Weinigel, linux-kernel

Al Boldi wrote:
> Christer Weinigel <christer@weinigel.se> wrote:
> 
>>>eCos is nice enough -- because it's mostly C :)
>>
>>And those parts that are C++ (from a 2 year old eCos dist) won't
>>compile with a modern g++.
> 
> 
> C++ is OO,

But not a very good implementation of it :-(.

> and OO is great!  OO is the natural way of doing things, and 
> allows one to concentrate on the issues at hand, while leaving the 
> nitty-gritty to the compiler to decide.
> 
> And this is the problem, as kernel development is highly sensitive to 
> compiler output, and which is why there are parts written in asm and others 
> in C.
> 
> So rewriting C with C++ would be as dumb as rewriting asm with C.
> 
> But there may be certain higher level parts in the kernel that could benefit 
> from rewriting C with C++, much the same as lower level parts have benefited 
> from rewriting them in asm.
> 
> So we have a situation like this:
> 
> 	low-level written in asm when needed
> 
> 	main-level written in C mostly
> 
> 	high-level written in C++ when needed
> 
> Note though, C++ is not currently viable for kernel development, due to its 
> enormous overhead generated by immature compiler technology.  Once this has 
> matured, there should be no problem.
> 
> 
>>-- 
>>"Just how much can I get away with and still go to heaven?"
> 
> 
> Just know that HE is one and only one.
> 
> Thanks!
> 
> --
> Al
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


-- 
Peter Williams                                   pwil3058@bigpond.net.au

"Learning, n. The kind of ignorance distinguishing the studious."
  -- Ambrose Bierce

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
  2006-05-02 18:21 Al Boldi
@ 2006-05-02 20:28 ` J.A. Magallon
  2006-05-02 23:55 ` Peter Williams
  2006-05-03  8:09 ` Steven Rostedt
  2 siblings, 0 replies; 200+ messages in thread
From: J.A. Magallon @ 2006-05-02 20:28 UTC (permalink / raw)
  To: Al Boldi, Linux-Kernel, 

[-- Attachment #1: Type: text/plain, Size: 2200 bytes --]

On Tue, 2 May 2006 21:21:44 +0300, Al Boldi <a1426z@gawab.com> wrote:

> Christer Weinigel <christer@weinigel.se> wrote:
> >> eCos is nice enough -- because it's mostly C :)
> >
> > And those parts that are C++ (from a 2 year old eCos dist) won't
> > compile with a modern g++.
> 
> C++ is OO, and OO is great!  OO is the natural way of doing things, and 
> allows one to concentrate on the issues at hand, while leaving the 
> nitty-gritty to the compiler to decide.
> 
> And this is the problem, as kernel development is highly sensitive to 
> compiler output, and which is why there are parts written in asm and others 
> in C.
> 
> So rewriting C with C++ would be as dumb as rewriting asm with C.
> 
> But there may be certain higher level parts in the kernel that could benefit 
> from rewriting C with C++, much the same as lower level parts have benefited 
> from rewriting them in asm.
> 
> So we have a situation like this:
> 
> 	low-level written in asm when needed
> 
> 	main-level written in C mostly
> 
> 	high-level written in C++ when needed
> 

You can control low level features in C++ even much better than in asm.
Just an example. You can be pretty sure that a function like this:

inline void f(const int& x)
{
}

would use the parameter you pass to it without doing a copy on the stack.
And that is not dependent on anything.
For example, I wrote a vector library to do math with SSE, and there it
is fundamental that you don't _ever_ write a xmm register to the stack or
to memory in temporary variables. Look like this:

class Vector {
    float   f[4];

    typedef float __vr __attribute__((__mode__(__V4SF__),__aligned__(16)));
    
    Vector operator+(const __vr that) const
    {
	return __builtin_ia32_addps(...);
    };
    Vector operator-(const __vr that) const
    {
	return __builtin_ia32_subps(...);
    };
    ...
};

--
J.A. Magallon <jamagallon()able!es>     \               Software is like sex:
werewolf!able!es                         \         It's better when it's free
Mandriva Linux release 2006.1 (Cooker) for i586
Linux 2.6.16-jam11 (gcc 4.1.1 20060330 (prerelease)) #1 SMP PREEMPT Mon

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
@ 2006-05-02 18:21 Al Boldi
  2006-05-02 20:28 ` J.A. Magallon
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ messages in thread
From: Al Boldi @ 2006-05-02 18:21 UTC (permalink / raw)
  To: Christer Weinigel; +Cc: linux-kernel

Christer Weinigel <christer@weinigel.se> wrote:
>> eCos is nice enough -- because it's mostly C :)
>
> And those parts that are C++ (from a 2 year old eCos dist) won't
> compile with a modern g++.

C++ is OO, and OO is great!  OO is the natural way of doing things, and 
allows one to concentrate on the issues at hand, while leaving the 
nitty-gritty to the compiler to decide.

And this is the problem, as kernel development is highly sensitive to 
compiler output, and which is why there are parts written in asm and others 
in C.

So rewriting C with C++ would be as dumb as rewriting asm with C.

But there may be certain higher level parts in the kernel that could benefit 
from rewriting C with C++, much the same as lower level parts have benefited 
from rewriting them in asm.

So we have a situation like this:

	low-level written in asm when needed

	main-level written in C mostly

	high-level written in C++ when needed

Note though, C++ is not currently viable for kernel development, due to its 
enormous overhead generated by immature compiler technology.  Once this has 
matured, there should be no problem.

> -- 
> "Just how much can I get away with and still go to heaven?"

Just know that HE is one and only one.

Thanks!

--
Al


^ permalink raw reply	[flat|nested] 200+ messages in thread

* RE: Compiling C++ modules
@ 2006-04-28  9:37 Khushil Dep
  0 siblings, 0 replies; 200+ messages in thread
From: Khushil Dep @ 2006-04-28  9:37 UTC (permalink / raw)
  To: Avi Kivity, Davi Arnaut
  Cc: Willy Tarreau, Denis Vlasenko, dtor_core, Kyle Moffett, Alan Cox,
	linux-kernel

Have think about your own tag line mate. C is pure. A kernel should be
as pure as possible. Leave it alone folks - haven't we all been down
this road before? Why does everyone want to move higher and higher up
the ladder when it comes to languages? Does no one still love to code in
pure ASM any more or am I just stuck in the past? Leave complexity for
application programmers. System programmers should dream in binary and
talk ASM. :-)

-----------------------
Mr. W. A. Khushil Dep

-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of Avi Kivity
Sent: 28 April 2006 10:34
To: Davi Arnaut
Cc: Willy Tarreau; Denis Vlasenko; dtor_core@ameritech.net; Kyle
Moffett; Alan Cox; linux-kernel@vger.kernel.org
Subject: Re: Compiling C++ modules

Davi Arnaut wrote:
>>
>> Mozilla is written in C++ ? I start to better understand where the
>> 160 MB bloat comes from...
>>     
>
> Evolution is written in C.
>   

FWIW, userspace is moving away from C as unproductive and unsafe. KDE is

of course C++, mozilla, openoffice are C++, and gnome is moving towards 
(of all things) C#.

GCC considered adopting a C++ subset. My impressions of the discussion 
was that (a) a majority of the developers would like that (b) RMS would 
never allow it (c) there were concerns about bootstrap on platforms 
where a C++ compiler was not available.

Kernels of other operating systems (Windows, AIX (?)) allow C++. And 
don't start about Windows crashing whenever you sneeze at it - it's so
1998.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick
to panic.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 200+ messages in thread

* Re: Compiling C++ modules
       [not found]     ` <66grR-2DK-27@gated-at.bofh.it>
@ 2006-04-28  0:03       ` Robert Hancock
  0 siblings, 0 replies; 200+ messages in thread
From: Robert Hancock @ 2006-04-28  0:03 UTC (permalink / raw)
  To: linux-kernel; +Cc: Denis Vlasenko

Denis Vlasenko wrote:
>> Additionally, C++ guarantees that if an exception is thrown after 
>> spin_lock() is called, then the spin_unlock() will also be called. 
>> That's an interesting mechanism by itself.
> 
> Life gets even more interesting when you hit another exception
> inside destructor(s) being executed due to first one.
> Say, spin_unlock() discovers that lock is already unlocked
> and does "throw BUG_double_unlock".

You're not allowed to throw exceptions from inside the stack unwinding 
caused by another exception, terminate() gets called in this case. In 
most cases this isn't too hard to avoid, you just have to ensure that 
exceptions don't get thrown out of destructors. Your example isn't very 
good, why would you throw an exception in that case? The caller isn't 
going to be able to do anything useful with it since it's because of a 
coding bug, some kind of assert or BUG() would be more logical.

-- 
Robert Hancock      Saskatoon, SK, Canada
To email, remove "nospam" from hancockr@nospamshaw.ca
Home Page: http://www.roberthancock.com/


^ permalink raw reply	[flat|nested] 200+ messages in thread

end of thread, other threads:[~2006-05-13 16:21 UTC | newest]

Thread overview: 200+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-24 19:16 Compiling C++ modules Gary Poppitz
2006-04-24 19:27 ` Greg KH
2006-04-24 20:02   ` C++ pushback Gary Poppitz
2006-04-24 20:15     ` Christoph Hellwig
2006-04-24 20:16     ` Greg KH
2006-04-24 20:18     ` Martin Mares
2006-04-24 21:36       ` Jeff V. Merkey
2006-04-24 21:28         ` J.A. Magallon
2006-04-24 21:43           ` Harald Arnesen
2006-04-24 21:52         ` Alan Cox
2006-04-24 22:16           ` J.A. Magallon
2006-04-25  0:05             ` Harald Arnesen
2006-04-25  0:46               ` Diego Calleja
2006-04-25  9:12                 ` Harald Arnesen
2006-04-25  1:30             ` linux-os (Dick Johnson)
2006-04-25  2:58               ` marty fouts
2006-04-27 22:55               ` Bill Davidsen
2006-05-02 15:58                 ` Randy.Dunlap
2006-05-02 20:36                 ` David Schwartz
2006-04-25  8:15             ` Xavier Bestel
2006-04-25  8:42               ` Avi Kivity
2006-04-25  8:52                 ` Martin Mares
2006-04-25  9:00                   ` Avi Kivity
2006-04-25  9:05                     ` Martin Mares
2006-04-25  9:13                       ` Avi Kivity
2006-04-25  9:22                         ` Xavier Bestel
2006-04-25 20:20                           ` J.A. Magallon
2006-04-25 20:31                             ` Barry Kelly
2006-04-25  9:09             ` Nikita Danilov
2006-04-25 20:10               ` J.A. Magallon
2006-04-25 18:02             ` Geert Uytterhoeven
2006-04-27  9:09             ` Alexander E. Patrakov
2006-04-24 22:39           ` Willy Tarreau
2006-04-24 22:57           ` Jeff V. Merkey
2006-04-24 23:02       ` David Schwartz
2006-04-25  8:55         ` Martin Mares
2006-04-25  8:59           ` Jan Engelhardt
2006-04-25 14:37           ` David Schwartz
2006-04-25 19:50             ` Martin Mares
2006-04-26  2:33               ` David Schwartz
2006-04-26  3:42                 ` Matthew Frost
2006-04-26 19:25                   ` David Schwartz
2006-04-26 20:01                     ` Jan-Benedict Glaw
2006-04-26 20:09                       ` Linus Torvalds
2006-04-26 20:19                         ` Al Viro
2006-04-26 21:37                           ` Sam Ravnborg
2006-04-28  9:23                             ` Avi Kivity
2006-04-28 12:00                               ` linux-os (Dick Johnson)
2006-04-28 12:46                                 ` Jan-Benedict Glaw
2006-04-26 20:25                         ` Jan-Benedict Glaw
2006-04-26 20:43                         ` David Schwartz
2006-04-26 23:00                         ` Roman Kononov
2006-04-27  0:38                           ` Kyle Moffett
2006-04-27  2:05                             ` Roman Kononov
2006-04-27  3:37                               ` Kyle Moffett
2006-04-27  5:37                                 ` Roman Kononov
2006-04-27 13:58                                   ` Michael Buesch
2006-04-27 14:22                                     ` linux-os (Dick Johnson)
2006-04-27  8:07                                 ` Avi Kivity
2006-04-27 13:55                                   ` Denis Vlasenko
2006-04-27 14:27                                     ` Avi Kivity
2006-04-27 14:56                                       ` Denis Vlasenko
2006-04-27 15:54                                         ` Bob Copeland
2006-04-27 16:03                                         ` Avi Kivity
2006-04-27 15:00                                       ` Martin Mares
2006-04-27 15:31                                         ` Avi Kivity
2006-04-27 15:38                                           ` Martin Mares
2006-04-28  8:16                                             ` Avi Kivity
2006-04-28  8:30                                               ` Avi Kivity
2006-04-28 15:47                                               ` Jan Engelhardt
2006-04-28 15:51                                       ` Jan Engelhardt
2006-04-28 16:51                                         ` Avi Kivity
2006-04-27 14:50                                 ` Sam Ravnborg
2006-04-27  8:50                               ` Martin Mares
2006-04-27  3:57                           ` Willy Tarreau
2006-04-27  5:53                             ` Roman Kononov
2006-04-27  7:55                           ` Jan-Benedict Glaw
2006-04-27 17:20                           ` C++ pushback (when does this religious thread end?) Leonard Peterson
2006-04-30 17:48                           ` C++ pushback Jan Harkes
2006-04-30 20:55                             ` David Schwartz
2006-04-26 20:05                     ` linux-os (Dick Johnson)
2006-04-26 20:09                     ` Xavier Bestel
2006-04-26 20:44                       ` Randy.Dunlap
2006-05-02 20:09                         ` C++ pushback + sparse Randy.Dunlap
2006-04-27  7:49                       ` C++ pushback Jiri Kosina
2006-04-26 21:05                     ` Martin Mares
2006-04-25  7:33       ` Avi Kivity
2006-04-25  7:47         ` Nick Piggin
2006-05-13 16:21         ` Esben Nielsen
2006-04-24 20:36     ` Thiago Galesi
2006-04-24 21:38     ` Kurt Wall
2006-04-27 16:17     ` Roman Kononov
2006-04-27 21:59       ` Grant Coady
2006-04-27 22:09     ` Bill Davidsen
2006-04-27 23:19       ` Jan Knutar
2006-04-24 19:30 ` Compiling C++ modules Al Viro
2006-04-24 19:40 ` linux-os (Dick Johnson)
2006-04-24 20:54   ` Geert Uytterhoeven
2006-04-24 19:42 ` Alexey Dobriyan
2006-04-24 20:30 ` Daniel Barkalow
2006-04-24 20:35 ` C++ is in US [Re: Compiling C++ modules] Jiri Slaby
2006-04-24 20:45 ` Compiling C++ modules Alan Cox
2006-04-24 21:03   ` Avi Kivity
2006-04-24 21:23     ` Joshua Hudson
2006-04-24 21:29     ` Kyle Moffett
2006-04-24 21:50       ` marty fouts
2006-04-24 22:09         ` Martin Mares
2006-04-24 22:30           ` Willy Tarreau
2006-04-24 22:32           ` Joshua Hudson
2006-04-24 22:45           ` marty fouts
2006-04-25 15:32         ` Michael Buesch
2006-04-25  7:08       ` Avi Kivity
2006-04-25 10:23         ` James Courtier-Dutton
2006-04-25 15:59         ` Kyle Moffett
2006-04-25 16:46           ` Avi Kivity
2006-04-25 17:10             ` Dmitry Torokhov
2006-04-25 17:19               ` Avi Kivity
2006-04-25 17:28                 ` Dmitry Torokhov
2006-04-25 17:53                   ` Avi Kivity
2006-04-25 18:04                     ` Dmitry Torokhov
2006-04-25 18:08                     ` Valdis.Kletnieks
2006-04-25 18:26                       ` Avi Kivity
2006-04-25 18:38                         ` Avi Kivity
2006-04-25 18:52                           ` Michael Poole
2006-04-25 19:13                             ` Avi Kivity
2006-04-27 15:10                     ` Denis Vlasenko
2006-04-27 20:15                       ` Willy Tarreau
2006-04-27 21:08                         ` Davi Arnaut
2006-04-28  9:33                           ` Avi Kivity
2006-04-28 10:03                             ` Avi Kivity
2006-04-28 11:27                               ` Sergei Organov
2006-04-28 11:03                             ` Martin Mares
2006-04-28 11:30                               ` Avi Kivity
2006-04-28 15:56                                 ` Jan Engelhardt
2006-04-28 17:02                                   ` Avi Kivity
2006-04-28 17:38                                     ` linux-os (Dick Johnson)
2006-04-29  2:50                                       ` Christer Weinigel
2006-05-01 17:46                                       ` Dave Neuer
2006-05-01 20:21                                         ` Jan Engelhardt
2006-05-01 23:53                                         ` David Schwartz
2006-05-02  5:12                                           ` Willy Tarreau
2006-05-02 10:32                                             ` Avi Kivity
2006-05-02 11:15                                               ` Martin Mares
2006-05-02 11:26                                                 ` Avi Kivity
2006-05-02 11:40                                                   ` linux-os (Dick Johnson)
2006-05-02 12:42                                                   ` David Woodhouse
2006-05-02 16:27                                                     ` Christer Weinigel
2006-05-02 12:48                                                   ` Martin Mares
2006-05-02 13:52                                                     ` Avi Kivity
2006-05-02 14:13                                                       ` Al Viro
2006-05-02 14:54                                                         ` Avi Kivity
2006-05-02 16:16                                                   ` Brian Beattie
2006-05-02 16:21                                                     ` Avi Kivity
2006-05-02 13:21                                               ` Willy Tarreau
2006-05-02 14:41                                                 ` Avi Kivity
2006-05-02 22:25                                                   ` Diego Calleja
2006-05-02 13:34                                               ` Al Viro
2006-05-02 14:02                                                 ` Avi Kivity
2006-05-02 14:34                                                   ` Al Viro
2006-05-02 15:04                                                     ` Avi Kivity
2006-05-02 15:15                                                       ` Al Viro
2006-05-02 15:19                                                         ` Avi Kivity
2006-05-02 15:27                                                           ` Kyle Moffett
2006-05-02 15:30                                                             ` Avi Kivity
2006-05-02 15:28                                                           ` Al Viro
2006-05-02 15:51                                                             ` Avi Kivity
2006-05-02 15:24                                                         ` Kyle Moffett
2006-05-03 13:13                                           ` Mark Lord
2006-05-03 20:51                                             ` David Schwartz
2006-04-30 21:15                               ` Eric W. Biederman
2006-04-25 17:54                 ` linux-os (Dick Johnson)
2006-04-26  8:30                   ` Jan Engelhardt
2006-04-26 11:36                     ` linux-os (Dick Johnson)
2006-04-25 19:22             ` Kyle Moffett
2006-04-25 19:54               ` Michael Buesch
2006-04-25 20:24               ` Avi Kivity
2006-04-25 20:11             ` Bongani Hlope
2006-04-25 20:26               ` Avi Kivity
2006-04-25 21:02                 ` Valdis.Kletnieks
2006-04-25 21:15                   ` Avi Kivity
     [not found]                     ` <71a0d6ff0604251646g4fc90b3dr30a03b8606360e7f@mail.gmail.com>
2006-04-26  4:39                       ` Avi Kivity
2006-04-25 17:55           ` Geert Uytterhoeven
2006-04-24 21:58     ` Alan Cox
2006-04-25  7:20       ` Avi Kivity
2006-04-25  9:06         ` Matt Keenan
2006-04-25 20:29           ` Bongani Hlope
2006-04-25 20:37             ` Avi Kivity
2006-04-25 21:08               ` Bongani Hlope
2006-04-25  4:17     ` Martin J. Bligh
2006-04-25  5:30       ` Avi Kivity
2006-04-25  8:58         ` Sam Ravnborg
2006-04-25  7:56     ` Jakob Oestergaard
2006-04-25  9:03     ` Jan Engelhardt
2006-04-24 21:36   ` J.A. Magallon
     [not found] <65eLE-GJ-21@gated-at.bofh.it>
     [not found] ` <65zwH-61W-51@gated-at.bofh.it>
     [not found]   ` <65zZH-6Bw-23@gated-at.bofh.it>
     [not found]     ` <66grR-2DK-27@gated-at.bofh.it>
2006-04-28  0:03       ` Robert Hancock
2006-04-28  9:37 Khushil Dep
2006-05-02 18:21 Al Boldi
2006-05-02 20:28 ` J.A. Magallon
2006-05-02 23:55 ` Peter Williams
2006-05-03  8:09 ` Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.