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
Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Volte posted:

In this particular case I don't see why it's better than just
code:
#define TEAM_PREFIX_NAME_LENGTH 64
but the idea isn't terrible in general. The idea isn't to search for occurrences of the magic number 64, but to search for occurrences of a particular type of magic number, regardless of value. For example you could have something like
code:
#define BUFFER_SIZE(n) n
and find occurrences of that symbol to locate all the places that a buffer is being allocated, regardless of what the specific buffer size is, and on the other side, know what a particular value represents just by looking at it. In a functional programming language you might have a "BufferSize" type constructor that just wraps an int so that buffer allocation functions can't be called with magic numbers. This is kind of a similar thing in spirit, even if it doesn't actually interact with the type system.



Hammerite posted:

I'm glad I'm not the only one who cares about this


If you use that constant wherever the number 64 is being used in that specific capacity, as opposed to being used in some other capacity, then I guess it lets you search more specifically for that.

Like if you search for TEAM_PREFIX_NAME_LENGTH_64 then you don't get any results for TEAM_MAXIMUM_DILDO_COLLECTION_SIZE_64 or w/e even though they're both 64

... Yeah, I get that. The point was


code:

#define TEAM_PREFIX_NAME_LENGTH(n) n

is not what I would consider one of those.

Adbot
ADBOT LOVES YOU

Xarn
Jun 26, 2015

NihilCredo posted:

Yes, that's a compile-time check though, not a runtime check.

If you cast to void* and back, you should get your bits aliased without any runtime cast errors until you try to actually use the cat as if it were a dog and everything explodes, right?

After going back and rereading your post, I think I understand what you are talking about, but I also think that your definition is useless :v:

To me, and to a lot of other people, weak vs strong typing is not about whether types are checked at runtime, but rather about how explicit you have to be when bypassing the type system (and how sane are the built-in implicit conversions). As an example, "12345" * 2 resulting in 24690, would be considered weak typing by most people, even if the runtime performs 1000 checks to ensure that the lhs is either a number or a string and nothing else. Similarly, atoi("12345") * 2 resulting in 24690 is considered strong typing, even though C has absolutely insane set of implicit conversions and no runtime checks.

Xarn fucked around with this message at 15:10 on Mar 19, 2020

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Jabor posted:

It's something that HCI folks have been ragging on forever, but I'm not aware of it being done for you in a commonly-used framework or anything.

In our UI designs we mostly try to avoid reflowing existing content like that - but when it's inevitable, we have an appearance animation and clicks get ignored during that animation.

Well then I wish the people in charge of the Windows start menu at Microsoft were as attentive as you.

Volmarias posted:

... Yeah, I get that. The point was


code:
#define TEAM_PREFIX_NAME_LENGTH(n) n
is not what I would consider one of those.

No? I think it amounts to more or less the same thing. It's basically creating a searchable tag. The fact that it has an argument is a red herring, it could instead be a macro that expands to nothing and is used alongside the integer literal. Volte has expressed the idea better than I am doing

I mean I'm not saying I would do either of these things, just that I can see a rationale for why someone might do it.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Hammerite posted:

No? I think it amounts to more or less the same thing. It's basically creating a searchable tag. The fact that it has an argument is a red herring, it could instead be a macro that expands to nothing and is used alongside the integer literal. Volte has expressed the idea better than I am doing

I mean I'm not saying I would do either of these things, just that I can see a rationale for why someone might do it.

Volte pointed out, correctly, that a macro named BUFFER_LENGTH(n) has value. It communicates what the number is without any extra overhead. This is good.

Imagine if, looking through some Radium Code, you came across AWFUL_SIZE(n). You see code like


code:

addMore(AWFUL_SIZE(8))

And


code:

getNext(AWFUL_SIZE(20))

What do those magic numbers mean? What are they relevant for? There's no context, you've just changed #DEFINE AWFUL_SIZE_8 8 into a macro function that communicates just as much information. If you're doing it to be searchable, what are you even searching for?

Dr. Stab
Sep 12, 2010
👨🏻‍⚕️🩺🔪🙀😱🙀

Hammerite posted:

That's a good start, but it has the problem that it could frustrate a user who has faster than normal reaction times and did actually intend to click on the thing - and sees their click have no effect. It's also possible that a user who is well-used to a particular workflow within your UI would begin to anticipate when something is going to appear and achieve clicks on that thing at faster than normal reaction time. That user would also be frustrated.

I think at minimum, there would have to be some visual indication of when the thing is actually ready to receive clicks.

Really, there has to be a period where no action is achieved. You can either do the present system where users are frustrated, or you could look back in time and guess what users were trying to click on, which would be even more frustrating, or you can lock them out. You can accompany the lockout with some visual indication, such as appearing at a lower contrast than normal. The user frustration stems from "I clicked and the thing I expected to happen didn't happen" If you telegraph what's happening, I'm sure they won't mind having to wait a tenth of a second for their element to become active.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Volmarias posted:

Volte pointed out, correctly, that a macro named BUFFER_LENGTH(n) has value. It communicates what the number is without any extra overhead. This is good.

Imagine if, looking through some Radium Code, you came across AWFUL_SIZE(n). You see code like


code:
addMore(AWFUL_SIZE(8))
And


code:
getNext(AWFUL_SIZE(20))
What do those magic numbers mean? What are they relevant for? There's no context, you've just changed #DEFINE AWFUL_SIZE_8 8 into a macro function that communicates just as much information. If you're doing it to be searchable, what are you even searching for?

It seems to me that your AWFUL_SIZE example is fundamentally different because it doesn't communicate what it is for beyond that it's a "size", whereas TEAM_PREFIX_NAME_LENGTH is substantially more meaningful. It's a "team prefix name length"... whatever that is. It was my presumption that a "team prefix name length" is something meaningful in the problem domain that the codebase in question addresses.

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


TEAM_PREFIX_NAME_LENGTH is used exclusively for declaring the length of character arrays. I have the option of killing it and just using hardcoded numbers, so this particular horror has reached the end of its life.

JawnV6
Jul 4, 2004

So hot ...

pokeyman posted:

code:
#define TEAM_PREFIX_NAME_LENGTH(n) n
No worries boss, DRYed it right up.

i like this because it's a subtle error when someone puts in TEAM_PREFIX_NAME_LENGTH(3) and something blows up on unaligned access

the repeated thing is silly but when used consistently does have the effect of limiting acceptable lengths


still.. make it an enum

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
I seem to recall a UI with search suggestions where the suggestion under the element wouldn't change as long as your cursor was over it. I thought it was Chrome, but I can't reproduce it. Maybe they changed it.
The main issue with that approach is that it doesn't work on touchscreens.

Presto
Nov 22, 2002

Keep calm and Harry on.

ultrafilter posted:

code:
#define TEAM_PREFIX_NAME_LENGTH_4 4
#define TEAM_PREFIX_NAME_LENGTH_6 6
#define TEAM_PREFIX_NAME_LENGTH_8 8
#define TEAM_PREFIX_NAME_LENGTH_10 10
#define TEAM_PREFIX_NAME_LENGTH_12 12
#define TEAM_PREFIX_NAME_LENGTH_16 16
#define TEAM_PREFIX_NAME_LENGTH_24 24
#define TEAM_PREFIX_NAME_LENGTH_32 32
#define TEAM_PREFIX_NAME_LENGTH_64 64
#define TEAM_PREFIX_NAME_LENGTH_128 128
#define TEAM_PREFIX_NAME_LENGTH_256 256
#define TEAM_PREFIX_NAME_LENGTH_512 512
I don't know. I don't know.

Just use token pasting.

code:
#define TEAM_PREFIX_NAME_LENGTH(n) static const int TEAM_PREFIX_NAME_LENGTH_##n = n

TEAM_PREFIX_NAME_LENGTH(4);
TEAM_PREFIX_NAME_LENGTH(8);
TEAM_PREFIX_NAME_LENGTH(16);
TEAM_PREFIX_NAME_LENGTH(32);
TEAM_PREFIX_NAME_LENGTH(64);
TEAM_PREFIX_NAME_LENGTH(128);
TEAM_PREFIX_NAME_LENGTH(256);
TEAM_PREFIX_NAME_LENGTH(512);
There you go!

Kazinsal
Dec 13, 2011


Presto posted:

Just use token pasting.

code:
[snip]
There you go!

Not enough, because now you need to manually know what the static const ints are called!

code:
#define DECL_TEAM_PREFIX_NAME_LENGTH(n) static const int TEAM_PREFIX_NAME_LENGTH_##n = n
#define TEAM_PREFIX_NAME_LENGTH(n) (TEAM_PREFIX_NAME_LENGTH_##n)

DECL_TEAM_PREFIX_NAME_LENGTH(4);
DECL_TEAM_PREFIX_NAME_LENGTH(8);
DECL_TEAM_PREFIX_NAME_LENGTH(16);
DECL_TEAM_PREFIX_NAME_LENGTH(32);
DECL_TEAM_PREFIX_NAME_LENGTH(64);
DECL_TEAM_PREFIX_NAME_LENGTH(128);
DECL_TEAM_PREFIX_NAME_LENGTH(256);
DECL_TEAM_PREFIX_NAME_LENGTH(512);

if (team_prefix_name.length == TEAM_PREFIX_NAME_LENGTH(64))
{
    // foo
}
Problem solved!

Xarn
Jun 26, 2015
You are trying to make a joke, but you aren't even within the same order of magnitude of terribleness as the macros I have in prod. :v:

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I don't think anyone has used x macros yet

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Because X macros are great!

Spatial
Nov 15, 2007

I came across an inefficiency in C lately: in variadic functions a float is always widened to a double. On a desktop this is a nothingburger but on a microcontroller with only float32 hardware it turns a native single cycle operation into a multi-step process involving two conversions, stack alignments, etc.

This isn't optimal !!!! :anime:

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


"don't use variadic functions in embedded systems" seems like a pretty reasonable restriction.

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


ultrafilter posted:

"don't use variadic functions in embedded systems" seems like a pretty reasonable restriction.

yeah, but what if you could?

"...i just said you shouldn't."

yeah, yeah, sure! but...think about it....what if you could?!

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Cast float32s to int32s before using as a parameter to a variadic function boom done.

qsvui
Aug 23, 2003
some crazy thing
printf considered harmful

Spatial
Nov 15, 2007

Another solution: require that floats to be passed by pointer, assume this is always done and just dereference it. What could possibly go wrong?

In the spirit of C, I've done nothing wrong and you're just holding the footgun wrong :v:

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

qsvui posted:

printf considered harmful

yep

Qwertycoatl
Dec 31, 2008

We have printf but it's a custom implementation that doesn't understand %f and friends.

Athas
Aug 6, 2007

fuck that joker
C's weird quirk around everything turning into doubles is yet another example of poo poo That Is Wrong With C, and which has nothing to do with having to support low-level programming. It just sucks. Another example is the declaration syntax. The worst is the implicit conversions.

omeg
Sep 3, 2012

qsvui posted:

printf considered harmful

I'll take printf formatting over iostream any day.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Spatial posted:

I came across an inefficiency in C lately: in variadic functions a float is always widened to a double. On a desktop this is a nothingburger but on a microcontroller with only float32 hardware it turns a native single cycle operation into a multi-step process involving two conversions, stack alignments, etc.

This isn't optimal !!!! :anime:

I hate the implementation of variadic functions in C. It's so clunky - there's no mechanism for type safety of variadic function args in C, and many places ban them because of potential security vulnerabilities (e.g. format string vulnerabilities in printf, resolving this was one of the motivating factors behind the design of iostream in C++.) Even disregarding the security bullshit, there's all these parlor tricks it's doing with macros and the va_list poo poo that make me really hesitant to ever touch variadics in C if I can possibly help it.

Bruegels Fuckbooks fucked around with this message at 21:47 on Mar 20, 2020

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


Someone in the Haskell community did eventually come up with a type-safe printf, but it took the better part of a decade, and I'm not sure you could do what they did in any other language.

Qwertycoatl
Dec 31, 2008

C has essentially typesafe printf if you compile with -Wformat -Wformat-nonliteral -Werror, like you should

Absurd Alhazred
Mar 27, 2010

by Athanatos

omeg posted:

I'll take printf formatting over iostream any day.

Talk about damning with faint praise.

Xarn
Jun 26, 2015

Athas posted:

C's weird quirk around everything turning into doubles is yet another example of poo poo That Is Wrong With C, and which has nothing to do with having to support low-level programming. It just sucks. Another example is the declaration syntax. The worst is the implicit conversions.

Integer promotion rules

fritz
Jul 26, 2003

omeg posted:

I'll take printf formatting over iostream any day.

Use fmt unless you're some kind of barbarian

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

omeg posted:

I'll take printf formatting over iostream any day.

Thankfully it is no longer 1995 and those are not your only two options any more.

Winter Stormer
Oct 17, 2012

Plorkyeran posted:

Thankfully it is no longer 1995 and those are not your only two options any more.

yeah, now there's boost::format!

RPATDO_LAMD
Mar 22, 2013

🐘🪠🍆

Xarn posted:

Without a cast, you cannot downcast at all though.

C++ code:
struct Base {};
struct Derived : Base{};

void foo() {
    Base* bptr = nullptr;
    Derived* dptr = nullptr;
    bptr = dptr; // upcasting, always ok
    dptr = bptr; // compilation error
}


It's possible to static_cast or reinterpret_cast a pointer at compile time with no runtime checks at all. You have to explicitly opt in to runtime typechecking by deciding to use dynamic_cast, and it's "slower" so people are likely to skip it out of premature optimisation.

raminasi
Jan 25, 2005

a last drink with no ice

ultrafilter posted:

Someone in the Haskell community did eventually come up with a type-safe printf, but it took the better part of a decade, and I'm not sure you could do what they did in any other language.

F# (and apparently OCaml as well) has one, but it relies on special-casing within the compiler, which might count as cheating.

RPATDO_LAMD
Mar 22, 2013

🐘🪠🍆

raminasi posted:

F# (and apparently OCaml as well) has one, but it relies on special-casing within the compiler, which might count as cheating.

Rust has one!

Rust's println! macro basically just calls rust's version of ToString on every argument and then shoves all those into the format string, which AFAIK is a pretty much foolproof way to do printf entirely type-safely in any lang.
(Actually it calls 'fmt', which doesn't return a string but instead writes text to a "formatter" object, I guess like a C++ stream kinda thing? Presumably this helps to avoid creating a million unnecessary strings at runtime. And then there are a bunch of different functions that have to be defined on the type for it to work with the other printf specifiers like printing in binary or hexadecimal.)

Xarn
Jun 26, 2015
Just use std::format

Absurd Alhazred
Mar 27, 2010

by Athanatos
Just serialize into XML.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Absurd Alhazred posted:

Just serialize into XML.

Just dump in it hex. Kids these days, never had to read a core dump to figure out why their program doesn’t work. :corsair:

FlapYoJacks
Feb 12, 2009
Jesus gently caress stop creating duplicated code you fucks! Has anybody heard of a function before?

Adbot
ADBOT LOVES YOU

spiritual bypass
Feb 19, 2008

Grimey Drawer
Yes, I've heard they're slower than writing code inline

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