Hacker Newsnew | past | comments | ask | show | jobs | submit | TuxSH's commentslogin

> It shouldn't require casting from and to specific pointer types

You don't need to explicitly cast T* to void* (guaranteed to be safe), you only need to cast when converting out of void*.

The rules are basically the same as casting between pointer-to-derived-class and pointer-to-base-class and they make sense.


They make sense but reduce type safety, because once you add the cast the case might hide some real typing issue. I sympathize with the idea that the down-cast should be explicit though.

> They make sense but reduce type safety

Yes, downcasting can be unsafe and should be used carefully, but what's the alternative? At least in C++ you can't cast between unrelated types without an explicit reinterpret_cast (or C-style cast).


The point is that, there is nothing else to be done with a void pointer, other then downcasting it, and it needs to be downcasted to be used. There is no other check that somehow validates the cast, so there is no upside to requiring the cast, while it does potentially silence accidental casts once the type changed.

and you CAN use static_cast to convert from void*; this silently keeps working if you refactor the void* into a matching-type pointer later, while raising a compilation error if you refactor to a different-type pointer.

Yes, a static_cast would be safe, but then most C++ seems to use a C-style cast because it is less clunky and then is less safe than the corresponding C code. The issue is not that the downcast is unsafe (it is, but once you have a void pointer you already accepted this), but that it becomes even less safe by adding a C-style cast.

It is also not clear what is gained by forcing programmers to add a cast. Void pointers should be used sparingly anyway.


> but then most C++ seems to use a C-style cast

If C++ programmers do not use modern safety features, that's really their fault. C-style pointer casts should be flagged in code review.

> but that it becomes even less safe by adding a C-style cast.

At least in C++ there is a safer option. If you really want to be on the safe side, you can even to a dynamic_cast (assuming your code base allows RTTI).

> It is also not clear what is gained by forcing programmers to add a cast.

I think the point is to make it explicit and stand out.


Lack of ergonomics around static_cast is language problem. The "most safe" of the casts should not be this verbose.

I see your point. It would be nice if a C-style cast behaved like a static_cast in C++, but that's not possible because of backwards compatibility. At least with GCC/Clang you can disable C-style casts altogether with '-Werror=old-style-cast'. (Maybe there is a similar option for MSVC.)

Yes, this is something that would need a new language edition to properly fix. Compiler vendors could split -Wold-style-cast into separate warnings for static_cast and other usage though so that you can only ban one of them.

You don't even need to use assembly for this, the wait for interrupt typically involves side effects.

Closing a PR or issue still makes it discoverable in PR/issue search results, as opposed to deleting an issue.

This. But OP wanted special requirements to open a PR. I.e. if those requirements are not met the PR is never visible to all and so admins can reject spam PRs without giving them a platform.

We occasionally get traditional SPAM PRs pointing to their product. In that case it is very useful to clear out title, PR body and reset the commits as well, so none of that appears on the repo.

This is time consuming.

Unfortunately the PR and the PR author will forever be listed there and linking to their product anyway.


> Unfortunately the PR and the PR author will forever be listed there

If they've been doing that to the other repo (and especially if they're just a spam account), there's a good chance using the "report" button and/or contacting GH support directly can yield positive results, up to the spam account being deleted (and the PR is usually deleted).

Unfortunately this doesn't scale.


> Unfortunately this doesn't scale

Correct. I used to report them, but 3/4 years ago they made it more difficult to report anything because you have to explain what's wrong even when it's very clear.


The point of the article and of define_static_array is to convert stuff like constexpr std::vector to constexpr std::array.

New (and delete) can be used in constexpr functions, however memory "allocated" like that cannot leave the constexpr "sandbox" so to speak, therefore std::vector cannot be generated at compile-time, but std::array may.

If you are working with fixed-size data like LUTs, just use std::array [1]

[1] Make sure not to use std::to_array when embedding 200KB+ files, as it's a mere constexpr function and not a language construct and will exceed constexpr limits; either specify the size or use a C-style array in this case


Maybe there is some astroturfing going on, as is usually the case, but it's already known that Codex/Claude Code and their ilk have been ruining CTFs for a while.

And well, one can always prompt "review my feature branch" or "review this file for bugs" with these tools; code analysis plays into the strengths of LLMs far more than code generation, since false positives/hallucinations aren't a problem with the former.


You can of course run DS (and GBA) software on 3DS.

> My only hesitation is the firmware update

If you "hack" your 3DS you will not have to worry about sysupdates anymore. It is slightly more straightforward to do so if your system version is <= 11.14, and quite trivial if <= 11.3.

As for homebrew dev on 3DS, you have a lot more RAM and a "proper" CPU with somewhat modern CPU concepts (an actual OS, virtual memory, caches, multicore).

Unlike the DS and GBA, the 3DS has an actual GPU (well, kinda, it doesn't have programmable fragment shaders), which was designed around a custom flavor of OpenGL ES and it shows; citro3d is a shim, other than stateful state tracking and mem allocation, it mostly exposes the GPU hw as-is.

Overall, I think it is easier for people to get started with 3DS homebrew development and that it provides more transferable skills (w/r/t OpenGL-like APIs).

Disclaimer: I'm the lead maintainer of Luma3DS, am a core maintainer of libctru, and wrote significant parts of the exploit chains the guide uses. Feel free to ask around.


Luma3DS and the community around it is excellent; thank you TuxSH! Your community provides better software and better support than Nintendo does with all their trillion-Yen revenue available to them; you deserve to be proud of that achievement.


You're welcome!

By the way, I have something related rather large in the works, look forward for a "Show HN" ;) (hopefully this quarter!)

> better support than Nintendo does with all their trillion-Yen revenue available to them

Well, they had to develop the entire OS, all GUI applications and SDK (and docs, and tooling...). It would also be far from surprising if they moved significant headcount to developing the Switch after the 3DS launched (and considering the Wii U's apparent failure).

There have been traces of Switch 2 stuff in Switch 1 kernel 3 years (?) before the S2 launched, so, in terms of planning, this tracks.


The DS, more specifically the arm946e-s has an MPU, not a MMU (you're confusing it with the 3DS's Arm11). Not like it makes much of a difference anyway, you configure either once or twice then leave them be.

Honestly, I think why the GBA is more popular than the DS for that kind of thing is because it only has one screen (much less awkward to emulate), has high-quality emulators that are mostly free of bugs (mGBA most notably), and its aspect ratio is better than the DS anyway (3:2 upscales really well on 16:10 devices). That is to say, it's much easier to emulate GBA software on a phone or a Steam Deck than it is to emulate DS software.


gah, you're right, I was thinking of memory protection (as in, marking the relevant regions as read-write and read-execute) when I wrote MMU.

It's of course optional, and you can ignore it for trivial examples, but most games and SDKs will tweak it all the time when loading additional code modules from the cartridge.

It's just another way in which the DS is more complex to use properly without an SDK to do this for you - there's just more to think about. At least compared to how the GBA lacks all of this and the entire cartridge is mapped into memory at all times.


> forbidding women to wear jeans

This police ordinance from 1800 was abolished in 2013

> requiring permission of the husband to work

Repealed in 1965


> optional<T&>

This is a C++26 feature which will have pointer-like semantics, aren't you confusing it with optional<reference_wrapper<T>> ?


> every async "function call" heap allocates.

> require the STL

That it has to heap-allocate if non-inlined is a misconception. This is only the default behavior.

One can define:

void *operator new(size_t sz, Foo &foo)

in the coro's promise type, and this:

- removes the implicitly-defined operator new

- forces the coro's signature to be CoroType f(Foo &foo), and forwards arguments to the "operator new" one defined

Therefore, it's pretty trivial to support coroutines even when heap cannot be used, especially in the non-recursive case.

Yes, green threads ("stackful coroutines") are more straightforward to use, however:

- they can't be arbitrarily destroyed when suspended (this would require stack unwinding support and/or active support from the green thread runtime)

- they are very ABI dependent. Among the "few registers" one has to save FPU registers. Which, in the case of older Arm architectures, and codegen options similar to -mgeneral-regs-only (for code that runs "below" userspace). Said FPU registers also take a lot of space in the stack frame, too

Really, stackless coros are just FSM generators (which is obvious if one looks at disasm)


A stackful coroutine implementation has to save exactly the same registers that a stackless one has to: the live ones at the suspension point.

A pure library implementation that uses on normal function call semantics obviously needs to conservatively save at least all callee-save registers, but that's not the only possible implementation. An implementation with compiler help should be able to do significantly better.

Ideally the compiler would provide a built-in, but even, for example, an implementation using GCC inline ASM with proper clobbers can do significantly better.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: