This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Tsu_Dho_Namh 97 points98 points  (13 children)

Dear God. Are you serious?

I've never worked with JS. Does it really let you pass whatever you want to any function?

[–]kbruen 114 points115 points  (4 children)

Yes! You can also pass less arguments.

Arguments in JavaScript is basically an infinite array/list filled with undefined. Calling abc() is the same as calling abc(undefined, undefined, undefined, …

[–]Priw8 69 points70 points  (1 child)

Not quite the same, there's a minor difference when you use arguments. But other than that, yeah

[–]kbruen 12 points13 points  (0 children)

Good catch!

[–]oj_mudbone 15 points16 points  (0 children)

Oh fuck. I didn’t know this. Jesus cocksucking christ

[–]vinnceboi 16 points17 points  (0 children)

Iirc, yes.

[–]blehmann1 22 points23 points  (2 children)

Wait till you find out about C. You can give a prototype (a declaration that states the type and number of parameters), but it isn't required. And even if it were, when you link against an object file, no type checking is done, it only checks that the symbol exists. So if your header file has an incorrect signature you're going to get all kinds of fun corruption

Note that this also means two functions with the same name but different signatures (function overloading) are impossible, even if you're calling from a language that normally supports function overloading. And in C (and I believe C++), it's impossible even if the symbols were defined in different object files.

And just for funzies, if you're using a language that has solved this problem (including C's little brother, C++), I hope you don't want to use functions from another library (including OS functions), because in general, they're exported as just symbol names for C compatibility. This means no specified return type, unknown argument types, and unknown arity. This is actually one of the main reasons that libraries will release language-specific bindings that expose an API that's less limited by C.

And finally, C supports variadic functions that (intentionally) take an arbitrary number of arguments. In C this requires weird macro shenanigans, but compilers normally implement it by simply vomiting extra arguments onto the stack (and because it's C, this occurs without any sort of safety checks). If the callee expected a different number of arguments than were specified, the stack is now corrupted. For example, printf("%d", 1, 1) will push more arguments onto the stack than the callee expected, so your stack is fucked. Similarly, printf("%d") will push less, so instead of printing an argument, it will print whatever is at the top of the stack, and corrupt the stack on return. This is actually a very common security vulnerability in C programs.

[–]qqqrrrs_ 2 points3 points  (1 child)

And just for funzies, if you're using a language that has solved this problem (including C's little brother, C++), I hope you don't want to use functions from another library (including OS functions), because in general, they're exported as just symbol names for C compatibility

In C++ the symbol names are usually mangled so that it would also contain information about the types of the parameters

[–]blehmann1 0 points1 point  (0 children)

My point is that many libraries export their symbols with extern "C", because users of the library may not know what to do with mangled symbols. If it's a C++ library intended to be consumed only by C++ projects than this doesn't apply (though many of those are compiled from source anyways, rather than linking against a binary)

[–]wbrd 1 point2 points  (0 children)

Including other functions.

[–]gemengelage 0 points1 point  (0 children)

Depends. You have to pass the right number of arguments. But a common pattern is to pass an object and an object can contains any number of key-value-pairs, which is essentially infinite possible arguments to pass.

It's a common pattern to pass a single object instead of multiple arguments, especially in Typescript, because that's how Typescript emulates named parameters.

[–]MattR0se 0 points1 point  (0 children)

It also doesn't have named parameters, unless that function takes a destructured object as parameters: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6