-
Notifications
You must be signed in to change notification settings - Fork 610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unused variable/parameter cleanup #1321
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to label every "unused" thing the same way?
(looking at this like a "real" codebase you'd want to work on)
For example, in ascending order of "legitimate to keep but unused":
UNUSED s32 pad;
- There is no reason to keep this
Sched_Init(..., UNUSED UNK_TYPE arg3
- It is unclear if that argument is useful / what it's for
SkelCurve_Draw(UNUSED Actor* actor
- This argument is unused but you can imagine it having a purpose
is_proutSyncPrintf(UNUSED void* arg
- That argument is required to match the callback prototype, and this particular callback implementation simply has no use for it
I think (4) clearly deserves UNUSED
since there's no way around it: it cannot not have that argument.
(3) to me deserves it too, it seems fair to pass the actor for drawing something, an implementation pass may eventually make use of it and at that point it would be a pain to go back and add the argument to every call.
(2) and (1) I think would be straight up removed in a clean-up pass, they aren't justified to exist, so I wouldn't think they deserve UNUSED
To be clear with (2) and (1), labeling them UNUSED
feels like solving a warning in:
s32 i;
s32 j; // warning: j is unused
for (i=0;...
by silencing the warning:
s32 i;
UNUSED s32 j;
for (i=0;...
instead of just removing the unused thing:
s32 i;
for (i=0;...
I know we can't just remove the things but it doesn't make sense to silence the warnings that would definitely have been there in the original code too. We just can't fix everything unfortunately I guess.
Plus a lot of these pads are not actually pads, especially in actors, they're pending GameState recasts. Overall I'd say this is another thing that it's too early to do, since it doesn't actually do anything for us to turn off this warning. |
I agree that they would be removed, but since we can't do that I'd rather mark them with UNUSED, since we can do that at no detriment, and leave the removal step to others. Adding UNUSED doesn't inhibit their removal, nor is it particularly misleading as of course they are unused. If anything it makes it easier to remove/replace especially since we had a few variables named "pad.." that were actually used, so a simple pad regex is insufficient. Now with UNUSED a regex to remove them all is much simpler.
That can be said for all pads assuming they were once meaningful variables. As before, adding UNUSED doesn't inhibit future changes and again I argue it makes them easier to automatically replace in the future if we wanted. (I'm not up to date on the latest discussion on this but I recall some are hesitant on whether we even should implement the gamestate casts) |
fwiw I agree with tharo and think this is fine to do now. marking something as unused isnt going to cement it as unused forever |
I don't have a clear opinion on this topic yet but I'll try to give my current thoughts. Basically right now I feel like we shouldn't bother at all with including UNUSED macros for parameters, and probably not for pads either. For unused parameters I have actually found that warnings are often more painful than useful even in a real codebase, particularly in languages where the compiler can't figure out whether the unused argument is required for some reason (eg. to match a common function interface like action functions). They can even make things worse if you follow them strictly, since it's often good to leave unused parameters to show that some kind of data or state is available in that function and could potentially be used. For pads I think it's sort of pointless to have the UNUSED macro since they should already be named in a way that makes it clear they're not used. It does allow us to enable the unused variable warnings, but it's not like we gain much by having that warning enabled in the decomp repo itself, aside from ensuring pads aren't incorrectly named but that shouldn't really happen anymore with decompilation being done. So overall I don't know if it's worth bothering with it. The only real case where I agree this macro should be used is for variables that are properly named and set but not actually used, because that's a situation where the variable serves no purpose and should definitely be removed in a normal situation. Either way I think we should consider that a bunch of variables and/or parameters are going to be used in some versions and not others, so I don't know how viable it will be to have these UNUSED macros in the future. For instance are we going to ifdef versions just to have the macro or not on some parameters? 😰 |
So with the 1/2/3/4 cases I highlighted above,
Nice to see we agree on this 😎 |
Part of the rationale for why I think unused-parameter is worth accommodating for in the decomp repo, even if you wouldn't use it personally (and I'm certain you wouldn't be alone), I'd rather we get as close to default warnings as is reasonable and allow modders to make the choice on what they want to do with respect to warnings. Choosing to disable it is much easier than choosing to enable it, as the latter will then require the modder to do a lot of work to fix it or be swamped with many warnings from vanilla code which they wouldn't even touch otherwise, leading to horrible merge conflicts with upstream.
I really don't follow this viewpoint much at all. I think it's very odd to not mark the pads as unused, they are currently nothing but unused variables from our perspective and it only makes it easier to find/replace them.
I think this extends just as much to totally unused variables as well. Totally unused variables definitely tick both these boxes.
It gets us closer to default warnings which I believe is more beneficial for the sake of modding and making it more like a "real" codebase. I'd rather not leave something out that we can viably accommodate for and expect a modding repo to have to fill in for us, making it increasingly difficult for modding repos to merge with upstream.
I can see how it can get dicey with other versions, I don't have a good grasp on how much that will affect this admittedly, but I don't think it will change enough to render this totally unviable. |
So we just assumed different goals with this I guess, afaict: you are looking at this with the focus of "make warnings useful out of the box when modding from master", |
My opinion on this hasn't changed, however there may be a middle-ground with tagging the unused-warning-raising stuff differently depending on its category 1/2/3/4 (see my comment above #1321 (review) ) Like, 1 and 2 could be USELESS instead of UNUSED ( |
I don't mind the inline nonmatching macro, although if we were to use a macro we could use a dedicated macro for stack padding? I'm not so sold on the case for example (2) though. I don't think it's different enough to (3) to warrant doing anything different with it, |
I can concede on using
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job
I approve of the goal of the PR now (haven't looked at everything yet)
Co-authored-by: Dragorn421 <[email protected]>
@@ -2438,7 +2437,7 @@ s32 BgCheck_AnyLineTest3(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec | |||
* ignores `actor` dyna poly | |||
* returns true if any poly intersects the sphere, else false | |||
* `outPoly` returns the pointer of the first poly found that intersects | |||
* `outBgId` returns the bgId of the entity that owns `outPoly` | |||
* @bug `outBgId` always returns BGCHECK_SCENE due to a bug in `BgCheck_SphVsFirstDynaPoly` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch lol
@@ -2565,8 +2564,7 @@ void func_80B59A80(EnZl3* this, PlayState* play) { | |||
} | |||
|
|||
void func_80B59AD0(EnZl3* this, PlayState* play) { | |||
// todo look into | |||
Actor* thisx = &this->actor; // unused, necessary to use 'this' first to fix regalloc | |||
if (this) {} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Highlighting this for others to see
What's the most fake of the two?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function taking a base actor doesnt really make sense, unless all the other functions that lead up to this can.
its possible that they copy pasted the signature from a main function i guess??
it is interestingly the only function that gets called with both this
and play
in func_80B55444
. that fact doesnt really mean much, but its interesting
Co-authored-by: Dragorn421 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even after giving it more thought I really don't think we should have UNUSED
for arguments, since it's debatable and doesn't do much for us (besides making changes more difficult), plus it's incomplete. Also I think we at least need to figure out its impact on multi-version support and how we would deal with it.
I'm also not in favor of STACK_PAD
/STACK_PADS
, tho I'm not really opposed to those, but I have similar concerns regarding multi-version support. For instance, we need to figure out if we're okay with adding a bunch of version ifdefs in variable declarations just for the purpose of these macros (because that's almost certainly going to happen).
Could you demonstrate how I don't look forward to ifdef hell in stack variables either, but I don't see how stack padding being a macro would worsen it compared to a regular temp declaration |
Having UNUSED in arguments mostly just adds more stuff to keep track of, especially since a distinction is made between prototypes and actual function declarations (one having UNUSED while the other doesn't). So for instance if you're updating a function's arguments and/or name you might copy-paste it from the C file to update the header, but then you have to remember to remove the UNUSED while doing that (and we have to look for that in reviews). There are other minor consequences like modders having to remove the UNUSED if they want to use the argument, which can also lead to git conflicts for example. It's pretty small stuff overall tho, but it's an additional reason for me to dislike it.
For example if you have a variable which is used in some versions but not others, it could normally be handled by just having it declared in all versions, and only used in some (maybe with a comment like |
Inconsistency between function declaration and definition due to I don't think removing I didn't think of the case of a temp that would be used in only some versions, making it stack padding in others. I have no idea if that would be a rare occurrence or not |
I think this is going to be common, especially considering the amount of versions that have some features and not others (debug and ntsc vs pal), but I could be wrong on that. Also it's worth noting that this scenario could happen with arguments, and it's going to get really ugly if we have to ifdef inside function prototypes just to include/exclude UNUSED in one or even multiple arguments.
Since this PR enables unused warnings by default, it wouldn't be an option to not use STACK_PAD (or UNUSED), and afaik you can't have UNUSED on a variable that is actually used (at least I would expect the compiler to error on that). So I think we would always need some form of ifdef to avoid the warning. |
To make things clear, |
Wait really? GCC doesn't error or even warn if a variable declared unused is actually used? |
Yes, here's a fantastic one-liner for checking the behavior echo 'int main(){ int a; __attribute__((unused)) int b; int c; c=0; __attribute__((unused)) int d; d=0; }' | gcc -x c -Wunused-variable -fsyntax-only - |
Status update on this PR: Limbo Would be good to hear more opinions. (even if there was no discussion, we'd still need a contributor approval) Personally I understand Roman's concerns on ifdef'ing around unused stack variables, and it's bad we have zero visibility on how common/uncommon this scenario would be @Roman971 to put it simply do you "veto" this PR |
think we prob just need more opinions so far 2 (3 including tharo) people are ok with this vs 1 who is not. |
Linking to a short discussion about this PR to not lose it: https://discord.com/channels/688807550715560050/752770632357511239/1062683481378930730 |
With multiversion well underway, we should consider these changes again, as that seemed to be many people's biggest concern |
Throwing my two cents in: I think the purpose of this is to eventually enable |
Modding aside I still think its useful from a documentation standpoint. Currently the codebase mentions some things as "unused" in comments, whenever people documenting felt it was worth mentioning. This will standardize a way to see if something is unused and will be even less noisy then it being mentioned in a comment, imo. Plus the added benefits to modding, of course. I dont have much to say on the STACK_PAD conversation though |
Yeah for things like global variables, having an unused annotation is helpful (although the comment seems fine to me). But there are so many unused parameters that I'm not sure it's helpful overall to mark them all as unused. I guess at this point I'm not very surprised if a parameter is unused, or only used in debug, so I'd rather not have to read the annotation. That said, I can get used to it so it's not important to me, feel free to go ahead with this |
UNUSED
attribute to unused variables, enables checking-Wunused-variable
warnings now that they're all suppressed.UNUSED
attribute to unused parameters in boot and code, overlays have many action functions where one or more parameter is unused so I've left those alone for now. Since not all-Wunused-parameter
warnings are suppressed, I've left-Wno-unused-parameter
inCHECK_WARNINGS
.pad
that are used.pad
and for functions with multiple they are namedpad1
,pad2
, etc. Also renamed some padding variables with the same name in different scopes.