Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6568
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Thu Mar 27, 2014 11:06 pm UTC

Xanthir wrote:And of course, both of those fail if the limit is zero.


You're not supposed to notice that.

Anyway I normally do one condition for the first print, and a while loop for the rest. If you want to avoid copy-paste code you can wrap a condition around the whole thing, but no it's not the least code. It's not a big enough deal to me to warrant it being a major argument in a language decision. I'm not a big fan of optional syntax, but I can see the appeal for adding or removing items from a list. I'm neutral, leaning towards things being the way I'm used to.

That said, there are other cases where you might want to do something different for the first loop as well, so it might be nice to have a syntax for code that only gets executed on the first iteration of the loop.
Summum ius, summa iniuria.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Coding: Fleeting Thoughts

Postby Rysto » Thu Mar 27, 2014 11:11 pm UTC

Xanthir wrote:And of course, both of those fail if the limit is zero.

I don't see how mine fails on a zero-length list?

User avatar
Xanthir
My HERO!!!
Posts: 5400
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Thu Mar 27, 2014 11:18 pm UTC

Rysto wrote:
Xanthir wrote:And of course, both of those fail if the limit is zero.

I don't see how mine fails on a zero-length list?

Yours was posted after I started writing my comment, and I decided I didn't want to bother correcting my post for it, damn the chronology.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
felltir
has a sniper scope and a trigger finger.
Posts: 2493
Joined: Tue Mar 04, 2008 5:01 pm UTC
Location: Back in't home town. Never at home.
Contact:

Re: Coding: Fleeting Thoughts

Postby felltir » Thu Mar 27, 2014 11:32 pm UTC

Code: Select all

["10", "10", "10", "10"].map(parseInt)
makes me unhappy.
Spoiler:
RoadieRich wrote:He's a super flexible furry martial artist from London. She is a Rabbit breeding mad scientist from Michigan. They fight crime!
The Great Hippo wrote:I THINK THE SOLAR SYSTEM MIGHT BE AN ATOM OF OXYGEN.


Blog

he/him/his

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Thu Mar 27, 2014 11:38 pm UTC

Yakk wrote:"%d"_printf( x );
I honestly feel like this is a candidate for a "Most Pointlessly Obtuse Use of Language Syntax" award.

lgw
Posts: 437
Joined: Mon Apr 12, 2010 10:52 pm UTC

Re: Coding: Fleeting Thoughts

Postby lgw » Thu Mar 27, 2014 11:46 pm UTC

EvanED wrote:
Yakk wrote:"%d"_printf( x );
I honestly feel like this is a candidate for a "Most Pointlessly Obtuse Use of Language Syntax" award.


How is that I don't even?
"In no set of physics laws do you get two cats." - doogly

User avatar
phlip
Restorer of Worlds
Posts: 7569
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Mar 28, 2014 12:34 am UTC

felltir wrote:

Code: Select all

["10", "10", "10", "10"].map(parseInt)
makes me unhappy.

My favourite:

Code: Select all

>>> [] + []

>>> [] + {}
[object Object]
>>> {} + []
0
>>> {} + {}
NaN

Here's a bunch more

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Yakk
Poster with most posts but no title.
Posts: 11116
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Fri Mar 28, 2014 1:35 am UTC

EvanED wrote:
Yakk wrote:"%d"_printf( x );
I honestly feel like this is a candidate for a "Most Pointlessly Obtuse Use of Language Syntax" award.

Compile time user defined printf literal (using printf syntax), which returns a function object that knows the number and type of arguments, evaluated on `x`.

Fixes arg type and count errors (causing UB) common in printf code, and faster as it lacks runtime parsing of format string.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
felltir
has a sniper scope and a trigger finger.
Posts: 2493
Joined: Tue Mar 04, 2008 5:01 pm UTC
Location: Back in't home town. Never at home.
Contact:

Re: Coding: Fleeting Thoughts

Postby felltir » Fri Mar 28, 2014 10:04 am UTC

phlip wrote:
felltir wrote:

Code: Select all

["10", "10", "10", "10"].map(parseInt)
makes me unhappy.

My favourite:

Code: Select all

>>> [] + []

>>> [] + {}
[object Object]
>>> {} + []
0
>>> {} + {}
NaN

Here's a bunch more


wat
Spoiler:
RoadieRich wrote:He's a super flexible furry martial artist from London. She is a Rabbit breeding mad scientist from Michigan. They fight crime!
The Great Hippo wrote:I THINK THE SOLAR SYSTEM MIGHT BE AN ATOM OF OXYGEN.


Blog

he/him/his

User avatar
phlip
Restorer of Worlds
Posts: 7569
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Mar 28, 2014 3:18 pm UTC

Yep, that's exactly where I got that snippet from. Probably linked somewhere in this thread before. Good times.

A hint, for those who are trying to figure out why on earth JavaScript behaves like that:
Spoiler:

Code: Select all

>>> ({} + {})
[object Object][object Object]

And the answer:
Spoiler:
In JS, the binary + operator behaves like this: if both the operands are numbers, do addition, but if either is anything else, convert both to strings and concatenate. Converting an array to a string happens by converting each element to a string and joining them with commas... while an object literal doesn't have a custom toString method so it comes out as just the bland "[object Object]". This handles the first two, where the return values are the empty string and then the string "[object Object]", respectively.

But what of the other two? Why does it behave differently when the parameters are switched? Well, as the hint suggests, it's not actually being parsed as a single expression - that's why wrapping it in parens changes it. The example of "{} + []" would be more accurately represented as:

Code: Select all

{
}
+[]
That is, an empty block (not an empty object literal), followed by a unary + operator applied to an empty array. Which means it's going to try to convert the empty array to a number. The way it does that is by converting it to a string, and then reading that string as a number. Yes, really. Also, the empty string reads as 0. The upshot is that an empty array, treated as a number, is 0... a one-element array, when that element is a number, becomes that same number, while a two-or-more element array becomes NaN (since that comma messes it all up). Similarly, "+{}" becomes NaN because it can't parse "[object Object]" as a number.

Yay, JavaScript.

Speaking of well-designed languages, I'm sure you're all aware that PHP is a terrible language. But it turns out it used to be a terrible language. I mean wow.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Fri Mar 28, 2014 3:24 pm UTC

phlip wrote:Speaking of well-designed languages, I'm sure you're all aware that PHP is a terrible language. But it turns out it used to be a terrible language. I mean wow.
My favorite PHP fact is that:
  • When looking up functions, PHP uses the hash of the name of the function...
  • Early versions of PHP used strlen as the hash function (!)...
  • ...and so function names were chosen so that the lengths were reasonably distributed by length.
I haven't seen anything else that encapsulates my opinion/impression of PHP better than that. :-)

Source.

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Fri Mar 28, 2014 8:56 pm UTC

Hey now, it was important to optimize function lookups for those old computers. There werewas literally hundreds of functions to store.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

Wonderbolt
Posts: 212
Joined: Thu Mar 13, 2014 12:11 pm UTC

Re: Coding: Fleeting Thoughts

Postby Wonderbolt » Sat Mar 29, 2014 12:20 am UTC

EvanED wrote:Source.

This, combined with everything I've ever seen from PHP and Lerdorf makes me wonder whether he's not just pulling a ridiculously big prank on a ridiculous number of people.

heatsink
Posts: 86
Joined: Fri Jun 30, 2006 8:58 am UTC

Re: Coding: Fleeting Thoughts

Postby heatsink » Sat Mar 29, 2014 7:04 pm UTC

Yakk wrote:Type erasure is the process of taking a set of operations and abstracting them. Then, being able to take any type that supports those operations, and build an implementation that matches the abstraction.

In C++ we often type erase the ability to copy and destroy, which does require (for large erased types at least) free store allocation. But that is just a typical method of using the technique.


I t‌hink I see wha‌t you mean. T‌he internal language would include operations an‌d types th‌at ar‌e not resolved due to dependence o‌n template parameters, a‌nd t‌he compiler would both resolve t‌hese an‌d optimize t‌he parts th‌at have known types.

By t‌he way, why i‌s everyone spelling t‌hings weirdly?

User avatar
Dason
Posts: 1311
Joined: Wed Dec 02, 2009 7:06 am UTC
Location: ~/

Re: Coding: Fleeting Thoughts

Postby Dason » Sat Mar 29, 2014 7:14 pm UTC

heatsink wrote:
Yakk wrote:By t‌he way, why i‌s everyone spelling t‌hings weirdly?

Read the top announcement
double epsilon = -.0000001;

User avatar
Yakk
Poster with most posts but no title.
Posts: 11116
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting tought dem

Postby Yakk » Sat Mar 29, 2014 11:19 pm UTC

(Fixed Dason's quotes below)
Dason wrote:
heatsink wrote:By t‌he way, why i‌s everyone spelling t‌hings weirdly?

Read the top announcement

And fix your quotes Dason!
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Dason
Posts: 1311
Joined: Wed Dec 02, 2009 7:06 am UTC
Location: ~/

Re: Coding: Fleeting tought dem

Postby Dason » Sun Mar 30, 2014 2:12 am UTC

Yakk wrote:(Fixed Dason's quotes below)
Dason wrote:
heatsink wrote:By t‌he way, why i‌s everyone spelling t‌hings weirdly?

Read the top announcement

And fix your quotes Dason!

You bastard. How dare you criticize my typing impediment.
double epsilon = -.0000001;

troyp
Posts: 557
Joined: Thu May 22, 2008 9:20 pm UTC
Location: Lismore, NSW

Re: Coding: Fleeting tought dem

Postby troyp » Sun Mar 30, 2014 3:44 am UTC

Thesh wrote:

Code: Select all

i=0;
goto first;
do {
    print(',');
    first:
    print(i);
} while (++i<10)

Leaving aside the code itself, is that label indentation just an error or is it really meant to be like that? It seems terribly unreadable to me. Although I guess the right syntax highlighting scheme (maybe with bolded and underlined labels) might help. Personally, I'd put the do on the same line as the goto and outdent the label to the same level, so the whole thing looks like the custom control flow construct that it is.

Rysto wrote:me preferred method be:

Code: Select all

sep="";
for (int i = 0; i < 10; i++) {
    printf("%s%d", sep, i);
    sep=", ";
}

That's not too different from what I do in C++:

Code: Select all

for (int i=0; i<10; ++i)
    cout << (i==0 ? "" : ", ") << i;

User avatar
PM 2Ring
Posts: 3707
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting tought dem

Postby PM 2Ring » Sun Mar 30, 2014 4:32 am UTC

troyp wrote:
Thesh wrote:

Code: Select all

i=0;
goto first;
do {
    print(',');
    first:
    print(i);
} while (++i<10)

a leave aside de code itself, be dat label indentation just an error or y be really meant a be like dat? It seems terribly unreadable to me. Although I guess de right syntax highlighting scheme (maybe wid bolded an' underlined labels) might help. Personally, I'd put de do pon de same line as de goto an' outdent de label to de same level, so de whole ting looks like de custom control flow construct dat it be.


I'd indent it like this:

Code: Select all

i=0;
goto first;
do {
    print(',');
first:
    print(i);
} while (++i<10)

which makes it pretty clear that this is not an ordinary do loop.

troyp wrote:
Rysto wrote:me preferred method be:

Code: Select all

sep="";
for (int i = 0; i < 10; i++) {
    printf("%s%d", sep, i);
    sep=", ";
}

dat's no too different from wa I do in C++:

Code: Select all

for (int i=0; i<10; ++i)
    cout << (i==0 ? "" : ", ") << i;


Except that Rysto's version eliminates the ugly test. Tests can be expensive: it's not just the time to do the comparison, branches tend to screw up pipelining.

OTOH, your test is fairly benign, since it just selects between two string constants. And I guess a smart compiler could unroll the loop, effectively converting your form to Rysto's.

speising
Posts: 2350
Joined: Mon Sep 03, 2012 4:54 pm UTC
Location: wien

Re: Coding: Fleeting tought dem

Postby speising » Sun Mar 30, 2014 12:54 pm UTC

you think a string assignment inside the loop is more benign?

troyp
Posts: 557
Joined: Thu May 22, 2008 9:20 pm UTC
Location: Lismore, NSW

Re: Coding: Fleeting tought dem

Postby troyp » Sun Mar 30, 2014 1:47 pm UTC

PM 2Ring wrote:I'd indent it like dis:

Code: Select all

i=0;
goto first;
do {
    print(',');
first:
    print(i);
} while (++i<10)

I do too, although in this case I'd probably do this:

Code: Select all

i=0;
goto first; do {
    print(',');
first:
    print(i);
} while (++i<10)

Except dat Rysto's version eliminates de ugly test. Tests kyan be expensive: it no just de time a do de comparison, branches tend to screw up pipelining.

OTOH, you test be fairly benign, since it just selects between two string constants. an' I guess a smart compiler could unroll de loop, effectively converting you form to Rysto's.

I know it's "wastefully" testing a condition which is statically determined, but it's well worth it (even if the compiler doesn't unroll it, which it quite likely would). The inefficiency isn't a concern: I'm never printing enough that the comparison operations will amount to a significant time, and even if I were, the time taken by the IO would overwhelm the time taken for comparisons. In exchange for this insignificant "sacrifice", by using the ternary operator, you save 2 lines, eliminate the need to do setup before the loop body and localize the comma-printing logic, making the structure of the loop apparent at a glance. It seems like a no-brainer to me, but I guess opinions may vary. :-)

User avatar
Pesto
Posts: 737
Joined: Wed Sep 05, 2007 5:33 pm UTC
Location: Berkeley, CA

Re: Coding: Fleeting tought dem

Postby Pesto » Tue Apr 01, 2014 1:22 am UTC

It helps to read the documentation for the version of software you're using.

User avatar
felltir
has a sniper scope and a trigger finger.
Posts: 2493
Joined: Tue Mar 04, 2008 5:01 pm UTC
Location: Back in't home town. Never at home.
Contact:

Re: Coding: Fleeting tought dem

Postby felltir » Tue Apr 01, 2014 7:13 pm UTC

It's really cool to be able to create a fully functional app available on the big open net in about half a day that has real value.
Spoiler:
RoadieRich wrote:He's a super flexible furry martial artist from London. She is a Rabbit breeding mad scientist from Michigan. They fight crime!
The Great Hippo wrote:I THINK THE SOLAR SYSTEM MIGHT BE AN ATOM OF OXYGEN.


Blog

he/him/his

lvc
Posts: 20
Joined: Mon Jun 15, 2009 5:27 am UTC

Re: Coding: Fleeting Thoughts

Postby lvc » Wed Apr 02, 2014 12:09 pm UTC

EvanED wrote:What if you don't have the items for the list available a priori, e.g. you're streaming input->output and to construct ",".join(...) would require reading the entire input into memory? Or maybe things are available, but you're doing some transformation to get the individual list lines -- your ostream_iterator example, for instance, means that now you need a sequence of the transformed values.

", ".join doesn't require a sequence, only an iterable - in this kind of case, I would probably pass it a generator expression. Although, to be fair, it *does* create a sequence if it isn't given one, since it needs to iterate over the input twice. So, your memory concerns are potentially reasonable, but it doesn't need to make your code any more complex.

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Coding: Fleeting Thoughts

Postby tastelikecoke » Wed Apr 02, 2014 3:04 pm UTC

FT: I made a Component-based system for a networked fighting game we need for a school requirement. It still bugs me if what I did is necessary or I overengineered the whole thing.

The project's public btw. (Don't get the wrong idea. I'm not advertising our code or something, it's ugly and it's not even finished yet)

User avatar
Steax
SecondTalon's Goon Squad
Posts: 3038
Joined: Sat Jan 12, 2008 12:18 pm UTC

Re: Coding: Fleeting Thoughts

Postby Steax » Wed Apr 02, 2014 4:38 pm UTC

So PHP has (at least) 2 ways of combining arrays. Both sound completely unambiguous:

Code: Select all


$a 
+ $b; // because only strings can't be added together, who'd need that use case?
 


Code: Select all


array_merge
($a, $b);
 


But this is PHP - consistency has no place here!

Code: Select all

['foo' => 'bar'] + ['foo' => 'baz']; // becomes ['foo' => 'bar'] ; left side takes precedence for some fucking reason
 


Code: Select all


array_merge
(['foo' => 'bar'], ['foo' => 'baz']); // becomes ['foo' => 'baz'] ; right side takes precedence because I want to be a special snowflake
 


And even the inconsistencies are inconsistent (in a way)!

Code: Select all

['bar'] + ['baz']; // becomes ['bar'];
 


Code: Select all


array_merge
(['bar'], ['baz']); // becomes ['bar', 'baz']
 


Okay, fine, one's a union and one's a merge, but... Still. Goddammit.
Last edited by Steax on Thu Apr 03, 2014 12:24 am UTC, edited 1 time in total.

User avatar
Jplus
Posts: 1721
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: Coding: Fleeting Thoughts

Postby Jplus » Wed Apr 02, 2014 9:26 pm UTC

Eww.
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

User avatar
phlip
Restorer of Worlds
Posts: 7569
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Thu Apr 03, 2014 3:18 am UTC

Yeah, PHP has this problem where it likes to pretend that lists and dictionaries are close enough to the same thing, and that you can treat [a,b,c] and {0:a,1:b,2:c} the same, as two different views of the same thing. But usually the operations you want to do with one, and with the other, are different... if you were to remove b from the list, you'd expect to get [a,c], but if you were to remove b from the dictionary, you'd expect to get {0:a,2:c}, which are different even by PHP's reckoning.

And so you end up with some array functions are designed to treat numerically-keyed array elements in list-like fashion, ensuring that the indexes keep counting 0, 1, 2, etc in order up the items, while others are designed to treat all the key/value pairs together, whatever that means. And you can never tell by looking at the function name/signature, you have to read the docs.

And that's how you end up with sort vs asort vs ksort, all of which do completely different things, and have assorted behaviours when you pass them a index-keyed array, or an associative array, or a mixed array that has both numeric and string keys...

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
ahammel
My Little Cabbage
Posts: 2135
Joined: Mon Jan 30, 2012 12:46 am UTC
Location: Vancouver BC
Contact:

Re: Coding: Fleeting Thoughts

Postby ahammel » Thu Apr 03, 2014 4:29 am UTC

phlip wrote:Yeah, PHP has this problem[...]
Just the one?

phlip wrote:And that's how you end up with sort vs asort vs ksort, all of which do completely different things, and have assorted behaviours[...]
I see what you did there.
He/Him/His/Alex
God damn these electric sex pants!

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6568
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Thu Apr 03, 2014 4:36 am UTC

Now I want to make a language where the assignment operator acts on a different side depending on what the data types of the left and right hand side are.


"int = float" - cast int to float and assign to right side
"float = int" cast float to int and assign to right side
"int = int" assign to left side
"float = float" cast float on left side to int and assign to right side
Summum ius, summa iniuria.

User avatar
phlip
Restorer of Worlds
Posts: 7569
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Thu Apr 03, 2014 4:48 am UTC

ahammel wrote:Just the one?

That post originally started with the full:
The problem with PHP...

One of the problems with PHP, as there are several...

One of the many problems with PHP is that it likes to pretend that lists and dictionaries are the same thing.
but then I figured that would be way too long winded.

Though, I wish I could have figured out a way to finish with "To summarise the summary of the summary: PHP is a problem".

ahammel wrote:I see what you did there.

Unintentional, I promise.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
PM 2Ring
Posts: 3707
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting tought dem

Postby PM 2Ring » Thu Apr 03, 2014 6:05 am UTC

speising wrote:you think a string assignment inside the loop is more benign?

Sure, since I assume it'd compile down to simply loading the pointer to the static string data .


phlip wrote:Though, I wish I could have figured out a way to finish with "To summarise the summary of the summary: PHP is a problem".

The main problem with PHP is that people use it. On publicly-accessible Web sites. :)

But I must admit that finding fault with PHP is hardly sporting, it's like shooting fish in a barrel.

User avatar
Jplus
Posts: 1721
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: Coding: Fleeting Thoughts

Postby Jplus » Thu Apr 03, 2014 8:26 am UTC

Strangely, Lua also has "tables" that can act either as arrays or as dictionaries, but it seems to have avoided those PHP issues completely. Although that might also have something to do with the table library containing only five functions, all of which treat tables as arrays.
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

FLHerne
Posts: 41
Joined: Fri Jan 13, 2012 9:44 pm UTC

Re: Coding: Fleeting Thoughts

Postby FLHerne » Thu Apr 03, 2014 10:54 am UTC

So I had this bit of C++:

Code: Select all

std::vector<Coord> nbr_list;
if (c.x != 0 && c.y != 0) nbr_list.push_back({c.x - 1, c.y - 1});


Now, c.x and c.y are unsigned shorts, and the arguments to Coord's constructor are unsigned shorts. So this should be perfectly fine, right?

Nope. :x

Code: Select all

warning: narrowing conversion of ‘(((int)c.Coord::x) + -1)’ from ‘int’ to ‘uint16 {aka short unsigned int}’ inside { } [-Wnarrowing]
         if (c.x != 0 && c.y != 0) nbr_list.push_back({c.x - 1, c.y - 1});

But I didn't have a cast there! Nothing I'm adding is an int, or big enough to need an int, and there's no way the result can need an int either! :?

Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int.

Huh. Can't it realise that it's not 'narrowing' if it implicitly converted it without asking? :evil:

Is there a way I can shut gcc up? I'd rather not turn of -Wnarrowing altogether, because it might be useful if I'm an idiot with something else.

User avatar
Xenomortis
Not actually a special flower.
Posts: 1446
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Thu Apr 03, 2014 11:06 am UTC

Sure, you might be able to writer a compiler that could know that a narrowing immediately following an automatic promotion doesn't need a warning.
But that isn't what's happening; you have a narrowing following an operation on a wider type.

The way to "shut GCC up" is to perform the cast yourself, explicitly.

Code: Select all

if (c.x != 0 && c.y != 0) nbr_list.push_back( {(ushort) (c.x - 1), (ushort) (c.y - 1)} );

I can never remember the precedence rules for casts
Image

FLHerne
Posts: 41
Joined: Fri Jan 13, 2012 9:44 pm UTC

Re: Coding: Fleeting Thoughts

Postby FLHerne » Thu Apr 03, 2014 12:15 pm UTC

Xenomortis wrote:...but that isn't what's happening; you have a narrowing following an operation on a wider type.
The way to "shut GCC up" is to perform the cast yourself, explicitly.

Code: Select all

if (c.x != 0 && c.y != 0) nbr_list.push_back( {(ushort) (c.x - 1), (ushort) (c.y - 1)} );

I can never remember the precedence rules for casts

Now you say it, I can see why that's true. Thanks. :D

(Also, your smalltext was exactly what I did wrong when I tried something similar - I was accidentally casting c.x (to the type it already was!) before the subtraction, so the answer ended up as an int anyway. :oops:

EDIT: Actually, that wasn't necessary. It seems increment/decrement operators actually return the original type, so

Code: Select all

if (c.x != 0 && c.y != 0) nbr_list.push_back({--c.x, --c.y});
works just fine! Now, why wasn't I using those anyway?
EDIT2: What. There's a very obvious reason why I didn't use those before. :roll: :oops:
Last edited by FLHerne on Thu Apr 03, 2014 3:06 pm UTC, edited 1 time in total.

User avatar
Jplus
Posts: 1721
Joined: Wed Apr 21, 2010 12:29 pm UTC
Location: Netherlands

Re: Coding: Fleeting Thoughts

Postby Jplus » Thu Apr 03, 2014 2:49 pm UTC

Just to explicate what caused this issue: the literal 1 has type long int, not short int. That's what causes the entire expression to be of type long int.

An aside: preferably use static_cast<short> rather than (ushort). This is C++, thank you.
"There are only two hard problems in computer science: cache coherence, naming things, and off-by-one errors." (Phil Karlton and Leon Bambrick)

coding and xkcd combined

(Julian/Julian's)

FLHerne
Posts: 41
Joined: Fri Jan 13, 2012 9:44 pm UTC

Re: Coding: Fleeting Thoughts

Postby FLHerne » Thu Apr 03, 2014 3:18 pm UTC

Jplus wrote:Just to explicate what caused this issue: the literal 1 has type long int, not short int. That's what causes the entire expression to be of type long int.
This isn't true; 'short int + short int' also returns an int (and not a long int, although they're likely the same size).
I quoted an explanation of the actual reason in my original question.

Jplus wrote:An aside: preferably use static_cast<short> rather than (ushort). This is C++, thank you.
Nope. That's 11 extra characters to type in order to make it less clear than it would be otherwise. :twisted: static_cast<x> is great for downcasting inherited thingies, because it's conspicuous and matches dynamic_cast<>, but it's far too cumbersome to stick in the middle of expressions just to change the type of an integer.

/me ponders a Religious thread if there isn't one yet

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Thu Apr 03, 2014 4:37 pm UTC

C# wins. I'm a bit surprised everything thrown into C++ there isn't some shorthand like this.

1L => long
1m => decimal
1d => double
1f => float

Nyktos
Posts: 138
Joined: Mon Mar 02, 2009 4:02 pm UTC

Re: Coding: Fleeting Thoughts

Postby Nyktos » Thu Apr 03, 2014 5:01 pm UTC

C (and presumably C++) has suffices like that, but there isn't one for shorts, probably because shorts are implicitly cast to ints when you look at them funny anyway.
Last edited by Nyktos on Thu Apr 03, 2014 5:04 pm UTC, edited 1 time in total.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 15 guests