Ada wants to catch as much as it can before runtime. To that end, it is one strict beast when you're used to all the willy nilly (and unsafe) constructs that we can beat C into doing. Ada absolutely is harder; it's built for hard problems. I don't intend to turn away from the topic of TFA, but Ada is on quite a different plane than C for a number of reasons--reasons that I think are compelling. C is wonderful for creating a foundation for low-level software as it has demonstrated for what seems like an eternity, but beyond that--and I think the crazy things we've done over time to make it a little easier to use reflect this--something with more high-level, safe, readable, yada, yada, yada is desirable if not absolutely needed.
Dynamic allocations in Ada are a cinch by the way. We use the "new" reserved word.
subtype Hacker_News_Article_ID is Natural; -- Numbers 0 .. Integer'Last;
type Article_Handle is access all Hacker_News_Article_ID; -- "all" reserved word used allows access to variables on the stack.
Favorite_Article : aliased Hacker_New_Article_ID := 3793716; -- "aliased" so we can point to this stack variable.
Article_Pointer : Article_Handle := Favorite_Article'Access; -- A sensible default perhaps.
later on...
Article_Pointer := new Hacker_News_Article_ID (Whatever);
Good luck!