Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Steve French
Sep 8, 2003

Ugg boots posted:

Where does it say that 00000001 is 1?

Now, I agree that doing &1 to test for even/odd is silly, but this is a pretty dumb point. If you can't assume something as elementary as that, then bitwise operations quickly become nearly (completely?) useless.

Adbot
ADBOT LOVES YOU

Steve French
Sep 8, 2003

Ugg boots posted:

What if, for example, a system only had a floating point math processor, so all integers are floating point numbers. Ignoring the precision problems, & 0x01 would not tell you if the number is even or odd, but in all representations it would give you the least significant bit.

Well, considering we are talking about C, and in C bitwise operators may only be applied to integral operands, then that's another pretty bogus "what if."

It's entirely reasonable to assume that the representation of a particular positive integer value is its binary equivalent (aside from endian-ness issues)

Steve French
Sep 8, 2003

shrughes posted:

If I were floWenoL, I would be posting "Look how stupid you are." Bitwise anding a floating point representation with the floating point representation of 1 won't give you the least significant bit; it will give you some power of 2 or NaN. Arguing a point by bringing up these fantasmical scenarios is worthless jerkery.

Not even that. As I said above, bitwise operators don't even work with floating point operands:

"error: invalid operands to binary &"

Steve French
Sep 8, 2003

nebby posted:

I'll admit I'm naive here, but I think the weakness of MD5 is a little more constrained than that at this point. Maybe someone who knows more about it can chime in, but I thought the general state of MD5 is "if you're using it today it's not quite an open door yet, but you should think about migrating" not "oh poo poo everyone who has MD5 hashes in their database is hosed!"

Edit: Not sure, but I think it's basically "we can find two colliding documents" not so much "give us a document, we'll find a colliding one for it." You can use the former to exploit systems, but I think if you use salts and so on you're still theoretically in decent shape right now with MD5. But generally speaking it's probably a matter of time until someone comes up with a generic solution. And yes, I wikipedia'ed it!

check it out, these 4 all have the same MD5 hash:

http://dl.getdropbox.com/u/67189/final1.ps
http://dl.getdropbox.com/u/67189/final2.ps
http://dl.getdropbox.com/u/67189/final3.ps
http://dl.getdropbox.com/u/67189/final4.ps

But yeah, the strong collision resistance is broken, but as far as I know, the weak collision resistance (given a message, it is hard to create another message such that their hashes are equal) and pre-image resistance (given a hash it is hard to find a message with that has) are still mostly okay for now. (with the above caveats mentioned by nebby)

Steve French
Sep 8, 2003

Presto posted:

Just now found a classic:
code:
i = (++i) % j;
...in 5 places in the same file.

Well hey, at least it isn't
code:
i = (i++) % j;

Steve French
Sep 8, 2003

mr_jim posted:

Christ, that's terrible even for single-point-of-return advocates. Usually they'll stick with creating extraneous variables for return values. Abusing a loop statement to avoid using a return statement is just awful.

Honestly I think he'd have been better off in that case just using a goto

Steve French
Sep 8, 2003

RussianManiac posted:

i have seen following things at my job

code:
#if 0
.... some code ...
#endif
Apparently it is how they comment it out.

I think this is an entirely reasonable thing to do and not a coding horror at all.

Commenting out large blocks of code is a bitch for a few reasons, including:
- usually the commented out code will not be syntax highlighted in most (all?) editors, making it harder to tell what it does/did while reading the code without removing the comments
- you can't just /* ... */ block comment poo poo out because the code might have some of that style comment inside it.

Steve French
Sep 8, 2003

Janin posted:

This applies to #if 0 ... #endif also

Hrm, apparently you're right, at least in vi. I usually use #ifdef NEVER or some other such thing, which keeps syntax highlighting.

Ryouga Inverse posted:

Yeah, checking in commented out code is terrible. You're using source control for that reason, just take it out.
I think this depends somewhat on the context, the team size, and the stage of development. I think that for a small team in early rapid stages of development, that sort of checkin is fine, if its code that for some reason doesn't work right quite yet (or is temporarily non-functional), but will be added soon. Especially if your team is in the habit of doing a lot of small commits; if you know that a piece of code is likely to be used soon, its a lot easier to leave it in there temporarily for other people to see, and not have to go back and dig it out of a previous revision.

Of course, for a more mature project with a larger team, there should be more stringent rules about checking poo poo in, and in those cases checking in commented out code is less reasonable.

Steve French
Sep 8, 2003


My favorite part of this is where he demonstrates that he doesn't understand what a filesystem is:

fatwood posted:

Acronis does a lot of things, but most of all it's drive imaging software, a fancy GUI over the rsync command.

Steve French
Sep 8, 2003

ChickenOfTomorrow posted:

Are switch statements suddenly considered harmful?

That would still be a horror with a switch statement

Steve French
Sep 8, 2003

Tei posted:

Is like somebody in the c language design trough basic error handling it something worth enough to embed in the compiler initialization code, or something.

what

Steve French
Sep 8, 2003

yaoi prophet posted:

Perl. The reason and binds weaker than assignment is so you can do something like

code:
$result = foo() or die "what the gently caress?\n"
# which is equivalent to
($result = foo()) or (die "what the gently caress?\n")
(which will evaluate foo(), store it in $result, and then fatally exit if that value is false-y) and they decided to make 'and' have similar precedence.

Ruby also has this (presumably PHP and Ruby both inherited it from Perl); the idea is basically that &&/|| are for boolean logic operations, and and/or are for control flow.

Steve French
Sep 8, 2003

I find that stylistically in ruby it makes more sense sometimes to do "A and B" instead of "B if A" or "if A; B; end", in situations where A is a significant operation.

For example if A was to perform a database operation, or call some computationally expensive method, I'd probably use and. If A were some simple boolean logic, I'd be more inclined to use if.

Steve French
Sep 8, 2003

het posted:

In terms of convention (in Perl at least) it probably partially originates with shell scripting, where using && and || for conditional execution of successive commands is not uncommon.

Yeah that too for sure (earlier examples of "or die" also); I was just giving an example of when I find myself using and instead of if.

Steve French
Sep 8, 2003

Ithaqua posted:

I find it pointless given that there are actual IDEs available because it's 2013.

More pointless than having an argument about text editors and IDEs? Doubtful.

Steve French
Sep 8, 2003

Hughlander posted:

So you are saying that bools should coerce to floats and we have functions that compare them with an epsilon like nearlyTrue and nearlyFalse?

https://www.youtube.com/watch?v=yzitqjUI6ok

Steve French
Sep 8, 2003

xtal posted:

Ruby code:
$ irb
>> true and 'a'
=> "a"

Lua code:
$ lua
> print(true and 'a')
a

I think it's the same in Perl, JavaScript and virtually every other language in use. Ironically, PHP is the only example I could find that doesn't behave that way.

You're not trying hard enough

Steve French
Sep 8, 2003

necrotic posted:

The difference is the alias will automatically pick the correct parent branch to rebase against. Removes the need to remember what you branched off of.

No, that's not true. The command that he gave will just allow you to make edits to the string of changes you've to the current working branch (edit, squash, delete), but will keep the same merge-base.

Just doing a rebase on master will actually rebase the commits.

If you have:

pre:
D F
| |
C E
|/
B
|
A
where master points to D and the current branch points to F, and then do the command given above with the merge-base, the merge-base command finds the merge-base between D and F (B) and rebases on that. So if you run that and squash E and F together into G, you get:

pre:
D
|
C G
|/
B
|
A
but if instead you just 'git rebase master' and do the same thing, the result is:

pre:
G
|
D
|
C
|
B
|
A

Steve French
Sep 8, 2003

Jewel posted:

Edit: Actually I think that's my problem. I don't like how "Time" means "Time Of Day" instead of "Time". Time of day is a useless marker that serves only to guide us in [a bunch of useful things], rather than something that should be used in computers.

Steve French
Sep 8, 2003

Manslaughter posted:

That's what typeof() is for. I actually like that the sorting is left to the developer, because you can't blame the language for doing it wrong/inserting crap data into your sort.

Allowing use of a caller-specified comparator function does not preclude the language from having sane default sort behavior.

Steve French
Sep 8, 2003

Why are you uploading the javascript files via a web application?

Steve French
Sep 8, 2003

Also,

code:
>>> sorted([10, 2, 10, 2])
[2, 2, 10, 10]
>>> sorted([10, 2, '10', '2'])
[2, 10, '10', '2']
edit: looks pretty insane to me

Steve French
Sep 8, 2003

NFX posted:

Numbers sort lower than strings, "10" sorts lower than "2" (it's not a natural sort). Seems sane?
code:
>>> sorted(["10", "2", 10, 2])
[2, 10, '10', '2']
>>> cmp(0, "0")
-1
I mean, it's arbitrary but it's better than mixing types (let the type class's cmp-overload handle it).

Sorry, my sarcasm wasn't sufficiently clear. I think it's much more sane behavior than JavaScript's given the posed constraint that it doesn't fail altogether (which IMO is the best behavior, you shouldn't be sorting on heterogenous collections without specifying a comparator yourself)

Steve French
Sep 8, 2003

Except that sorting an array of integers lexicographically is not sane. Maybe giving not-meaningful results when sorting a heterogeneous array when an explicit comparator is not given, as python does, is not sane either.

However, I care a lot more about behavior when doing something reasonable (e.g. sorting an array of integers), than I do about behavior when doing something unreasonable (e.g. sorting an array of varying types without explicitly defining a comparison function for sorting.

Furthermore, it's not really clear that in the general case JavaScript's behavior is meaningful either. When the specific example is all numbers, either as integers or strings, yeah, JavaScript looks like it behaves reasonably (at the expense of sanity when sorting just numbers). But what is a meaningful sort of the following, and what would you expect JavaScript to return?

[1, 2, 5, 3,[3, 4], { "foo": "baz" }, { "foo": "bar" }, "things", 56.23, "[object Object]", "[object Objecs]"].sort()

Steve French
Sep 8, 2003

nananananana

code:
> function isUndefined(v) { if (v == undefined) { return true; } else { return false; } }
  undefined
> [undefined, undefined, undefined].map(isUndefined)
  [true, true, true]
> Array(3).map(isUndefined)
  [undefined × 3]

Steve French
Sep 8, 2003

That's a lot of concern for something that shouldn't really matter, because why are you sorting arrays with items of different types in the first place? It just seems like throwing out the baby with the bath water to me.

And really, you can't think of a better way than always iterating the array to see if the items are all numbers? Well, lets temporarily assume that that is the best way; not the end of the world really since that's an O(n) operation and the sort itself is going to be O(n log n). But that's still sorta lovely, right, since we don't want to be paying that cost all the time when we're just sorting strings, etc. So let's think of something better but still kinda hokey; just start sorting based on the type of the first object in the array, and if you encounter a different type, instead of throwing an error like other languages do, just start sorting over again based on the new information. Now you've got pretty normal sort performance for arrays of numbers and arrays of strings (the ought-to-be-common-case that you ought to care about), and worst case a constant factor penalty of about 2 for heterogeneous arrays.

Or of course the array object could just keep track of what sorts of items are in it as those items are added and removed.

Finally, saying one aspect of the language design is the only sane option given other aspects of the language design is not really a valid defense to criticisms of the language design.

I admit that it seems somewhat problematic that sub-arrays might sort differently than the whole array, but I also think it is problematic that arrays of numbers sort lexicographically. This is a lovely tradeoff imposed by the "feature" that sorting heterogenous arrays works the way it does, which does not seem like a valuable feature to me.

Steve French
Sep 8, 2003

Harik posted:

I see this kind of bandaid programming all the time and it infuriates me. It's got so much code-rot going on - usually it comes with a bunch of "fixes" commented out because they didn't work, and correct code also commented out and replaced with fragile hacks because they didn't take the time to figure out what is actually wrong.

I think this is my favorite bandaid code:
C++ code:
void broken(unsigned char limit, unsigned char persentage) {
    unsigned long warning;

    // warning = limit * persentage;
    for (i=0;i<persentage;i++)  //Multiplies persentage and trigger. Normal multiplication does not work. Why?
        warning += limit;
    warning = warning/100;

    // ... do stuff
}
Hrm yes why wouldn't a*b work properly oh well instead of fixing it I'll just do a for-loop!

I can't read "persentage" without also seeing brain damage. And uhhh nice uninitialized variable there also

Steve French
Sep 8, 2003

2banks1swap.avi posted:

In one interview, I had to determine if a string was a palindrome. I confused C#'s with Java's substring parameters; one uses substring(StartIndex, EndIndex) and the other did substring(StartIndex, LengthFromThere). The guy was a smug gently caress about it, too, and it was hardly a secret at the time I had more experience with Java. This was all on a whiteboard with no references at all, and it was a very obvious honest mistake.

I probably dodged a bullet, though, that just reeks of insufferable bullshit.

What sort of solution did you have that required using a substring method?

Steve French
Sep 8, 2003

Yeah, I can't think of any reason to use a substring method when checking for a palindrome. piratepilates' code was about the closest I could think of to something reasonable, but it would be a lot easier and simpler to just reverse the whole string and skip the substring bit if you're gonna go that route.

Perhaps this is related to the real reason the guy was being a smug rear end in a top hat?

Steve French
Sep 8, 2003

But could you answer my question?

Steve French
Sep 8, 2003

Is it? Can you show an elegant tail recursive solution?

also, just because scala

code:
  s.view == s.view.reverse

Steve French fucked around with this message at 02:12 on Feb 3, 2014

Steve French
Sep 8, 2003

Deus Rex posted:

this would be cool in a language that uses structural sharing for strings, I guess.

Allocating n/2 extra strings is cooler than allocating 1 extra string

Steve French
Sep 8, 2003

evensevenone posted:

plebs and your languages without pointers.
C code:
int isPalindrome(char * s,int len) {
   if (len < 2) return 1;
   else if (s[0] != s[len-1]) return 0;
   else return isPalindrome(&s[1],len-2);
}


If you're going to build a shed with pointers,
C code:
int isPalindrome(char *s, size_t len) {
  char *e = s + len - 1;
  while (s < e) if (*s++ != *e--) return 0;
  return 1;
}

Steve French
Sep 8, 2003

Admiral H. Curtiss posted:

You also lose information about leading zeroes, or formatting information like spaces, braces, or hyphens. It's a terrible idea to store a phone number as an actual number.

A good point about leading zeroes, and I'm certainly not saying storing it as a number isn't awful, but when would you really care about formatting information? I guess it could be useful to distinguish between phone numbers in different areas of the world that might have the same number/sequence of digits. But presumably some normalization to complete numbers with country codes would solve all of the above issues.

Steve French
Sep 8, 2003

Ender.uNF posted:

This happens every time someone posts about interview questions. Some of you nerds just can't help making it into an e-penis contest instead of focusing on, you know, the actual discussion. Hey everyone, look at meeeeeeeeee!

Wait, so are you participating in the actual discussion?? Here I thought it was reasonable to talk about code.

I helped start the "derail" by asking some pointed questions intended to highlight the possibility that someone had misunderstood why their interview performance was perceived as poor.

THEN I put forth my entry in the e-penis contest because guess what? I actually enjoy thinking of and implementing various solutions to these sorts of problems.

AND I ended up learning something from it. From shrughes, who you all seem to hate for some reason or another. Maybe be less upset about things I guess?

Steve French
Sep 8, 2003

Okay, let me recap and make sure I'm understanding this correctly. Please correct any misunderstandings or inaccuracies.

The C standard says, in 6.5.6, regarding additive operators:

quote:

7: For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

quote:

8: When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.
(emphasis added)

So, in my code, the char *s parameter, in the context of that function, does not point to an element in an array, so it behaves like a pointer to the first element of an array of length one. Results of the operation that point to anything that is not in the array or one past the end of the array are undefined, so s - 1 is undefined.

Is this correct?

Steve French
Sep 8, 2003

Sure, that's what I meant by undefined in this context. But otherwise, you agree with my summary and interpretation?

Steve French
Sep 8, 2003

Ok I have to admit at this point that I was feigning ignorance a bit in my last post. That explanation cannot possibly be right, or there's a big problem with the standard library, because how else would you write a strlen function with the correct behavior?

Steve French posted:

So, in my code, the char *s parameter, in the context of that function, does not point to an element in an array, so it behaves like a pointer to the first element of an array of length one. Results of the operation that point to anything that is not in the array or one past the end of the array are undefined, so s - 1 is undefined.

C code:
size_t strlen(const char *s);
So, in this code, the const char *s parameter, in the context of this function, does not point to an element in an array, so it behaves like a pointer to the first element of an array of length one. Results of an operation that point to anything that is not in the array or one past the end of the array result in undefined behavior, so s + 2 has undefined behavior.

So 6.5.6.7, as quoted above, that dictates that s is treated like a pointer to an array of size one, must not quite apply directly in either of these cases.

So how is the pointer treated in the context of 6.5.6.8? Because if it's the above, then seemingly any operation on a string function argument accessing more than just the first two characters has undefined behavior (the standard doesn't seem to treat going more than one past the end of an array any differently than going before the start of the array). The compiler can't always know what the array being passed into the function looks like, either. If I compiled my palindrome function into a shared library, it seems that in order to guarantee correct behavior on elements that *are* within the array bounds (unknown to the compiler, and even to the compiled code at runtime), the compiled output must have sane behavior for all possible pointer inputs (except for those that result in overflows, of course).

At any rate, even if this is actually undefined behavior and bad, someone should probably tell the folks in charge of glibc:

C code:
char *
STRNCPY (char *s1, const char *s2, size_t n)
{
  char c;
  char *s = s1;

  --s1;
...

Steve French
Sep 8, 2003

Dessert Rose posted:

If you pass a pointer to something that isn't an array of characters to this function, it's you causing the undefined behavior, not the function.

You're missing the point, which is that according to the above interpretation of the standard that I believe to be wrong, s + 2 is undefined. So, you know, strlen("foo") would result in undefined behavior.

Adbot
ADBOT LOVES YOU

Steve French
Sep 8, 2003

Dessert Rose posted:

No, because strlen("foo") results in us entering the body of strlen with a const char *s pointing to the first element of a four-element char array ['f', 'o', 'o', 0]. In this context s+2 is defined.

Which would be awfully nice for the compiler to know, but it doesn't.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply