www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interesting GCC extensions

reply bearophile <bearophileHUGS lycos.com> writes:
Beside the known ones, like computed gotos and __builtin_expect(), GCC has
other less known extensions, you can find some of them here:
http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/

They are used by Linux. If D wants to be a system language, such small things
may be useful if you want to build a kernel with D.

One of them is the Range extension, it seems GCC devs think that 3 points are
better after all:

	switch (major_idx) {
	case 0:
		return SCSI_DISK0_MAJOR;
	case 1 ... 7:
		return SCSI_DISK1_MAJOR + major_idx - 1;
	case 8 ... 15:
		return SCSI_DISK8_MAJOR + major_idx - 8;
	default:
		BUG();
		return 0;
	}


Triple points can be used for initializations too:
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };


The __builtin_return_address() looks interesting, but I don't understand where
it can be useful.


The Constant detection done with __builtin_constant_p(exp) is what I was asking
for in one of my recent posts here. It seems I was "right" again.


The article also shows some of the function attributes, in truth in GCC there
are many other of such attributes. Some of them are useful for D too.

The good thing of adding some of those things to D is that they can be put in
the specs, so they don't become nonstandard extensions as in GCC, this avoids
several troubles. 

Bye,
bearophile
Sep 28 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Mon, Sep 28, 2009 at 12:35 PM, bearophile <bearophileHUGS lycos.com> wro=
te:
 Beside the known ones, like computed gotos and __builtin_expect(), GCC ha=

 http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/

 They are used by Linux. If D wants to be a system language, such small th=

 One of them is the Range extension, it seems GCC devs think that 3 points=

 =A0 =A0 =A0 =A0switch (major_idx) {
 =A0 =A0 =A0 =A0case 0:
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return SCSI_DISK0_MAJOR;
 =A0 =A0 =A0 =A0case 1 ... 7:
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return SCSI_DISK1_MAJOR + major_idx - 1;
 =A0 =A0 =A0 =A0case 8 ... 15:
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return SCSI_DISK8_MAJOR + major_idx - 8;
 =A0 =A0 =A0 =A0default:
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0BUG();
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return 0;
 =A0 =A0 =A0 =A0}


 Triple points can be used for initializations too:
 int widths[] =3D { [0 ... 9] =3D 1, [10 ... 99] =3D 2, [100] =3D 3 };


 The __builtin_return_address() looks interesting, but I don't understand =

 The Constant detection done with __builtin_constant_p(exp) is what I was =

 The article also shows some of the function attributes, in truth in GCC t=

 The good thing of adding some of those things to D is that they can be pu=

avoids several troubles. I think it's kind of silly that you constantly whine to Walter whenever he adds new features saying "why don't we fix the problems that already exist in D like the module system," and then turn around suggesting we add a bunch of features. Which do you want? Do you want new features, or do you want things to be fi= xed?
Sep 28 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Jarrett Billingsley:

Which do you want? Do you want new features, or do you want things to be fixed?<

The ideas shown in that post are low priority, so they can wait. But things can be planned for the future too, you can start thinking/planning about them even years before they are implemented (see vector operations of D). (The triple point syntax is probably out of time). Bye, bearophile
Sep 28 2009
prev sibling next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
bearophile wrote:

 Beside the known ones, like computed gotos and __builtin_expect(), GCC has
 other less known extensions, you can find some of them here:
 http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/
 
 They are used by Linux. If D wants to be a system language, such small
 things may be useful if you want to build a kernel with D.
 
 One of them is the Range extension, it seems GCC devs think that 3 points
 are better after all:
 
 switch (major_idx) {
 case 0:
 return SCSI_DISK0_MAJOR;
 case 1 ... 7:
 return SCSI_DISK1_MAJOR + major_idx - 1;
 case 8 ... 15:
 return SCSI_DISK8_MAJOR + major_idx - 8;
 default:
 BUG();
 return 0;
 }
 
 
 Triple points can be used for initializations too:
 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

That's cool, but the triple point syntax was shot down by Andrei on grounds of it complicating the parsing iirc. D already has .., I don't remember this being in C++.
 
 The __builtin_return_address() looks interesting, but I don't understand
 where it can be useful.
 
 
 The Constant detection done with __builtin_constant_p(exp) is what I was
 asking for in one of my recent posts here. It seems I was "right" again.

We don't need an extension for this! Look: template Eval(string exp) { enum Eval = mixin(exp); } template IsConstant(string exp) { enum IsConstant = __traits(compiles, Eval!exp); }
 
 The article also shows some of the function attributes, in truth in GCC
 there are many other of such attributes. Some of them are useful for D
 too.
 
 The good thing of adding some of those things to D is that they can be put
 in the specs, so they don't become nonstandard extensions as in GCC, this
 avoids several troubles.
 
 Bye,
 bearophile

I think most of the stuff that could be in the spec is covered by __traits. __traits is also easily extended without breaking anything else. Some things mentioned in the article are very implementation specific though.
Sep 28 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Lutger:

 We don't need an extension for this! Look:
 
 template Eval(string exp)
 {
     enum Eval = mixin(exp);
 }
 
 template IsConstant(string exp)
 {
     enum IsConstant = __traits(compiles, Eval!exp);
 }

From what I see I think your code is useless for my purposes: // D2 code import std.stdio: writeln; template Eval(string exp) { enum Eval = mixin(exp); } template IsConstant(string exp) { enum IsConstant = __traits(compiles, Eval!exp); } template Tuple(T...) { alias T Tuple; } template Range(int stop) { static if (stop <= 0) alias Tuple!() Range; else alias Tuple!(Range!(stop-1), stop-1) Range; } long ipow(long x, int n) { long result = 1; static if (IsConstant!("n")) { pragma(msg, "constant"); static if (n < 5) { foreach (i; Range!(n)) result *= x; } else { for (int i; i < n; i++) result *= x; } } else { pragma(msg, "not constant"); for (int i; i < n; i++) result *= x; } return result; } enum int w = 5; void main() { int x = 2; const int y = 3; enum int z = 4; writeln(IsConstant!("x"), " ", IsConstant!("y"), " ", IsConstant!("z"), " ", IsConstant!("w")); // prints: false false false true ipow(10, x); ipow(10, y); ipow(10, z); } Even "z" is seen as not constant? Bye, bearophile
Sep 28 2009
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
bearophile wrote:

 Lutger:
 
 We don't need an extension for this! Look:
 
 template Eval(string exp)
 {
     enum Eval = mixin(exp);
 }
 
 template IsConstant(string exp)
 {
     enum IsConstant = __traits(compiles, Eval!exp);
 }

From what I see I think your code is useless for my purposes: // D2 code import std.stdio: writeln; template Eval(string exp) { enum Eval = mixin(exp); } template IsConstant(string exp) { enum IsConstant = __traits(compiles, Eval!exp); } template Tuple(T...) { alias T Tuple; } template Range(int stop) { static if (stop <= 0) alias Tuple!() Range; else alias Tuple!(Range!(stop-1), stop-1) Range; } long ipow(long x, int n) { long result = 1; static if (IsConstant!("n")) { pragma(msg, "constant"); static if (n < 5) { foreach (i; Range!(n)) result *= x; } else { for (int i; i < n; i++) result *= x; } } else { pragma(msg, "not constant"); for (int i; i < n; i++) result *= x; } return result; } enum int w = 5; void main() { int x = 2; const int y = 3; enum int z = 4; writeln(IsConstant!("x"), " ", IsConstant!("y"), " ", IsConstant!("z"), " ", IsConstant!("w")); // prints: false false false true ipow(10, x); ipow(10, y); ipow(10, z); } Even "z" is seen as not constant? Bye, bearophile

They are not compile time constants. Have you tried it with GCC? It gives the exact same results.
Sep 28 2009
parent Lutger <lutger.blijdestijn gmail.com> writes:
Lutger wrote:

 bearophile wrote:
 
 Lutger:
 
 We don't need an extension for this! Look:
 
 template Eval(string exp)
 {
     enum Eval = mixin(exp);
 }
 
 template IsConstant(string exp)
 {
     enum IsConstant = __traits(compiles, Eval!exp);
 }

From what I see I think your code is useless for my purposes: // D2 code import std.stdio: writeln; template Eval(string exp) { enum Eval = mixin(exp); } template IsConstant(string exp) { enum IsConstant = __traits(compiles, Eval!exp); } template Tuple(T...) { alias T Tuple; } template Range(int stop) { static if (stop <= 0) alias Tuple!() Range; else alias Tuple!(Range!(stop-1), stop-1) Range; } long ipow(long x, int n) { long result = 1; static if (IsConstant!("n")) { pragma(msg, "constant"); static if (n < 5) { foreach (i; Range!(n)) result *= x; } else { for (int i; i < n; i++) result *= x; } } else { pragma(msg, "not constant"); for (int i; i < n; i++) result *= x; } return result; } enum int w = 5; void main() { int x = 2; const int y = 3; enum int z = 4; writeln(IsConstant!("x"), " ", IsConstant!("y"), " ", IsConstant!("z"), " ", IsConstant!("w")); // prints: false false false true ipow(10, x); ipow(10, y); ipow(10, z); } Even "z" is seen as not constant? Bye, bearophile

They are not compile time constants. Have you tried it with GCC? It gives the exact same results.

Actually not for z, I don't know why this doesn't work with dmd. It does say it is a constant.
Sep 28 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Sep 2009 12:58:57 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Jarrett Billingsley:

 Which do you want? Do you want new features, or do you want things to  
 be fixed?<

The ideas shown in that post are low priority, so they can wait. But things can be planned for the future too, you can start thinking/planning about them even years before they are implemented (see vector operations of D). (The triple point syntax is probably out of time).

Just so you know. In 5 months, (i.e. the future) nobody is going to remember that you posted this. I've noticed you replied to many a thread with "well, that's exactly what I suggested X months ago, but nobody listened to me." When you make 2 posts a week suggesting changes, you can't expect them all to be considered, most are lost in the noise. If you want something to be considered to be an enhancement, go through the proper channel -- bugzilla. Then it won't get lost. Mark it as an enhancement if necessary. -Steve
Sep 28 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Mon, Sep 28, 2009 at 1:27 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 On Mon, 28 Sep 2009 12:58:57 -0400, bearophile <bearophileHUGS lycos.com>
 wrote:

 Jarrett Billingsley:

 Which do you want? Do you want new features, or do you want things to b=



 fixed?<

The ideas shown in that post are low priority, so they can wait. But things can be planned for the future too, you can start thinking/plannin=


 about them even years before they are implemented (see vector operations=


 D).
 (The triple point syntax is probably out of time).

Just so you know. =A0In 5 months, (i.e. the future) nobody is going to remember that you posted this. =A0I've noticed you replied to many a thre=

 with "well, that's exactly what I suggested X months ago, but nobody
 listened to me." =A0When you make 2 posts a week suggesting changes, you =

 expect them all to be considered, most are lost in the noise.

 If you want something to be considered to be an enhancement, go through t=

 proper channel -- bugzilla. =A0Then it won't get lost.

 Mark it as an enhancement if necessary.

Hahahahaha. Hahahahahaha! You really think he's gonna do it? He won't. He won't even explain *why* he won't.
Sep 28 2009
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Mon, Sep 28, 2009 at 12:35:05PM -0400, bearophile wrote:
 Beside the known ones, like computed gotos and __builtin_expect(), GCC has
other less known extensions, you can find some of them here:
 http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/

I remember this page... did you post it here many months ago? Anyway: # define __must_check __attribute__((warn_unused_result)) That one looks kinda cool, though is mostly redundant since we have throw exceptions.
 One of them is the Range extension, it seems GCC devs think that 3 points are
better after all:

They are fools. What D has kicks ass. I actually used the case .. case in a program and it was just fantastic.
 Triple points can be used for initializations too:
 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

D's slicing can already do this I believe.
 The Constant detection done with __builtin_constant_p(exp) is what I was
asking for in one of my recent posts here. It seems I was "right" again.

Aye, that is cool. We should try to get some traits code together and make a std.reflection or something to do this stuff. -- Adam D. Ruppe http://arsdnet.net
Sep 28 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:
 Triple points can be used for initializations too:
 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

D's slicing can already do this I believe.

How? Bye, bearophile
Sep 28 2009
parent reply Rainer Deyke <rainerd eldwood.com> writes:
Adam D. Ruppe wrote:
 Trying it, I see it doesn't actually work in initialization, but you
 can do it after the fact easily enough:
 
 	int[101] a;
 	a[0..9] = 1;
 	a[10..99] = 2;
 	a[100] = 3;

This leaves elements 9 and 99 uninitialized. I assume the gcc version does not. -- Rainer Deyke - rainerd eldwood.com
Sep 28 2009
parent Rainer Deyke <rainerd eldwood.com> writes:
Adam D. Ruppe wrote:
 I think this makes D's syntax superior. We can say a[0..$] where
 gcc would have to use the more annoying a[0...$-1].
 (pretending the $ worked of course)

Although I generally prefer half-open ranges over closed ranges, both have their advantages and disadvantages. Advantages of half-open ranges: - Empty ranges are valid: [0 .. 0] - Easy for subranges to go to the end of the original: [x .. $] - Easy to split ranges: [0 .. x] and [x .. $] Advantages of closed ranges: - Symmetry. - Arguably easier to read. - ['a' ... 'z'] does not require awkward '+ 1' after 'z'. - [0 ... uint.max] is possible. -- Rainer Deyke - rainerd eldwood.com
Sep 28 2009
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Mon, Sep 28, 2009 at 03:45:16PM -0400, bearophile wrote:
 Adam D. Ruppe:
 Triple points can be used for initializations too:
 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

D's slicing can already do this I believe.

How?

Trying it, I see it doesn't actually work in initialization, but you can do it after the fact easily enough: int[101] a; a[0..9] = 1; a[10..99] = 2; a[100] = 3; Compiles fine on D2 and D1, and it uses memset() to set the array. Not quite the same, but pretty close. -- Adam D. Ruppe http://arsdnet.net
Sep 28 2009
prev sibling next sibling parent language_fan <foo bar.com.invalid> writes:
Mon, 28 Sep 2009 13:27:13 -0400, Steven Schveighoffer thusly wrote:

 On Mon, 28 Sep 2009 12:58:57 -0400, bearophile
 <bearophileHUGS lycos.com> wrote:
 
 Jarrett Billingsley:

 Which do you want? Do you want new features, or do you want things to
 be fixed?<

The ideas shown in that post are low priority, so they can wait. But things can be planned for the future too, you can start thinking/planning about them even years before they are implemented (see vector operations of D). (The triple point syntax is probably out of time).

Just so you know. In 5 months, (i.e. the future) nobody is going to remember that you posted this. I've noticed you replied to many a thread with "well, that's exactly what I suggested X months ago, but nobody listened to me." When you make 2 posts a week suggesting changes, you can't expect them all to be considered, most are lost in the noise.

You can filter out all posts not written by bearophile + the ones that are not roots of the discussion threads. :) They are mostly proposals. I do not know why he does not use the bugzilla - unintuitive interface perhaps? I have always tried to avoid bugzilla because of the horrible UI. More often, when I search for something, the search seems to be broken so I delegate the search to google.
Sep 28 2009
prev sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Mon, Sep 28, 2009 at 09:04:27PM -0600, Rainer Deyke wrote:
 	int[101] a;
 	a[0..9] = 1;
 	a[10..99] = 2;
 	a[100] = 3;

This leaves elements 9 and 99 uninitialized. I assume the gcc version does not.

That makes sense. I copied it literally without thinking. Easy enough fix. I think this makes D's syntax superior. We can say a[0..$] where gcc would have to use the more annoying a[0...$-1]. (pretending the $ worked of course) -- Adam D. Ruppe http://arsdnet.net
Sep 28 2009