Skip to main content
23 events
when toggle format what by license comment
Jul 21, 2017 at 13:46 comment added Ben Aaronson Let us continue this discussion in chat.
Jul 21, 2017 at 13:16 comment added Pete Kirkham The compiler already tracks whether or not it is assigned to. You haven't presented a case where the OP's suggestion creates an ambiguity which is not already dealt with by the existing definite assignment mechanism, so I don't see any advantage.
Jul 21, 2017 at 13:04 comment added Ben Aaronson @PeteKirkham So it takes a consistent approach to both: disallow at compile-time if it can't verify for sure at compile time that it is valid (i.e. that it has been declared and initialised). Allowing the OP's suggestion would prevent it from doing that, and so make it inconsistent. Does that answer your point? I may still be misunderstanding what you're saying, in which case could you expand on what you mean?
Jul 21, 2017 at 13:02 comment added Ben Aaronson @PeteKirkham The advantage the OP suggested to not creating scope is so that you could declare a variable in a try, then use it outside. As I showed, this can lead to a situation where the compiler doesn't know whether or not what you're written is valid- you may or may not have declared the variable by the time you use it. So instead, the compiler says this is always invalid, so you're safe at compile time. In the situation you're talking about (initialise in try, but not in catch), the compiler also says this is always invalid.
Jul 21, 2017 at 12:28 comment added Pete Kirkham If you agree that you'd get a more or less equivalent error whether or not the block created scope, your argument as to why the block creates scope is invalid.
Jul 21, 2017 at 12:20 comment added Ben Aaronson @PeteKirkham I'm not sure what you mean by "better than"? The compiler disallows both of these
Jul 21, 2017 at 12:11 comment added Pete Kirkham "Now you'd be trying to use an undeclared variable (firstVariable) if your method call throws." why is the error "the name 'firstVariable' does not exist in the current context" better than "use of unassigned local variable 'firstVariable'", which is what would happen if it is declared at the outer scope and not set to a value in the catch?
Jul 20, 2017 at 15:32 comment added Jules @SebastianRedl - try/catch is fundamentally different to switch. Note that it is at least theoretically possible in a try/catch statement to jump to the catch block from almost any point within the try block. In fact, if you declare a variable and then assign to it anything other than an expression whose value can be calculated at compile time, it is possible for an exception to be thrown that jumps to the catch block before it is initialized. Therefore, such a variable has no practical purpose, so making an exception to the scoping rules to allow this would not be worth doing.
Jul 20, 2017 at 12:15 history edited Ben Aaronson CC BY-SA 3.0
added 316 characters in body
Jul 20, 2017 at 10:54 comment added Ben Aaronson @svick Yes, that's true. In fact if you declare a variable outside a try...catch, then make sure to initialize it in both the try and the catch, the compiler does allow using that variable after the try...catch. The difference between that and what you're describing is just where the variable is declared. So perhaps I should undo my last edit.
Jul 20, 2017 at 10:43 comment added svick There is a difference between undeclared an uninitialized and C# tracks them separately. If you were allowed to use a variable outside the block where it was declared, it would mean you would be able to assign to it in the first catch block and then it would be definitely assigned in the second try block.
Jul 20, 2017 at 9:21 comment added Ben Aaronson @jpmc26 Good point, I've updated the answer
Jul 20, 2017 at 9:21 history edited Ben Aaronson CC BY-SA 3.0
added 18 characters in body
Jul 20, 2017 at 9:20 comment added Ben Aaronson @SebastianRedl I think Peter's reason is just as important as this one, if not more. But the OP explicitly said "Consistency-sake aside", so I was demonstrating that even if you wanted to make a special case for try/catch blocks (for some reason), you'd run into problems making it work
Jul 20, 2017 at 8:55 comment added Sebastian Redl I disagree with this answer. C# already has the rule that uninitialized variables cannot be read from, with some dataflow awareness. (Try declaring variables in cases of a switch and accessing them in others.) This rule could easily apply here and prevent this code from compiling anyway. I think Peter's answer below is more plausible.
S Jul 20, 2017 at 0:58 history suggested p13i CC BY-SA 3.0
Clarify what variable is undeclared
Jul 19, 2017 at 21:52 comment added jpmc26 For s static language like C#, declaration is really only relevant at compile time. The compiler could easily move the declaration earlier in the scope. The more important fact at runtime is that the variable might not be initialized.
Jul 19, 2017 at 21:00 review Suggested edits
S Jul 20, 2017 at 0:58
Jul 19, 2017 at 18:25 comment added Eliah Kagan "Now you'd be trying to use an undeclared variable if your method call throws." Furthermore, suppose this were avoided by treating the variable as though it had been declared, but not initialized, before the code that might throw. Then it wouldn't be undeclared, but it would still be potentially unassigned, and definite assignment analysis would prohibit reading its value (without an intervening assignment that it could prove occurred).
Jul 19, 2017 at 17:45 comment added Julia McGuigan catch(Exception e) - e wouldn't be in scope, or applicable - in later blocks or outside the catch. Try can contain some exception potential, like a method or code trying to establish a variable or context that could fail, e.g., opening a file/database connection, a web request. If that failed, you want to fall into an error state or retry, not try to access the result. You also probably don't even want to go into the second try without some null checks (depending on variable assignment), or your first throw may do some processing and re-throw (which is then caught up the chain somewhere else)
Jul 19, 2017 at 10:43 vote accept JᴀʏMᴇᴇ
Jul 19, 2017 at 10:34 comment added JᴀʏMᴇᴇ Ahh, this is exactly what I was after. I knew there were some language features that made what I was suggesting impossible, but I couldn't come up with any scenarios. Thanks very much.
Jul 19, 2017 at 10:33 history answered Ben Aaronson CC BY-SA 3.0