• calcopiritus@lemmy.world
    link
    fedilink
    arrow-up
    1
    ·
    48 minutes ago

    Can confirm. I have to do this all the time. Some coworkers just delete it, and I have to explain the situation every time when they see in the git blame that I put that semicolon there.

    As someone pointed out in another comment, in switch statements you should just start a new scope with {}. But in actual labels it’s just better to put a load-bearing semicolon. You don’t need to put it in another line though, I just put them like this:

    int main() {
        int *a = malloc(sizeof(*a));
        if (init_a(a) <= 0) {
            goto err;
        }
        do_something(a);
    err:;
        int ret = 0;
        if (a == NULL) {
            ret = -1;
        }
        free(a);
        return ret;
    }
    
  • SavvyWolf@pawb.social
    link
    fedilink
    English
    arrow-up
    54
    arrow-down
    1
    ·
    1 day ago

    You actually shouldn’t do this!

    This doesn’t introduce a new scope, so accidentally using x outside of the case block is UB. Instead you should introduce a new scope like so:

    switch (foo)  {
      case BAZ: {
        int x = ...;
        foobar(x);
      }
    }
    
    • Victor@lemmy.world
      link
      fedilink
      arrow-up
      3
      ·
      21 hours ago

      Is “case expr:” really a label? You could put anything in there, like “case 42:”. I don’t see a label, but maybe I don’t know what a label is in C.

      • TwilightKiddy@scribe.disroot.org
        link
        fedilink
        English
        arrow-up
        1
        ·
        14 hours ago

        In C# it’s certainly a label, it’s the same syntax and you can also jump to them with goto, which is actually very convenient sometimes. As far as I know this is an ancient feature and seeing how early C# was mostly inspired by C, I would expect it to behave the same way there.

        • Victor@lemmy.world
          link
          fedilink
          arrow-up
          1
          ·
          edit-2
          9 hours ago

          What?

          If I have a case 42: in C#, I can issue a goto 42 and resume execution after that case? Or how would that work?

          From what I know, labels are only an identifier followed by a colon, like:

          stop: printf("stopped.\n");
          

          Or just the label and colon on one line and statements following on subsequent lines. I’ve never seen a switch case expression being called a “label”. Very new to me. Would love to see a minimal demonstration example. 🙏

          Edit: huh, I guess you can.

          • TwilightKiddy@scribe.disroot.org
            link
            fedilink
            English
            arrow-up
            1
            ·
            48 minutes ago

            Yes, you would do goto case 42;
            From MSDN:

            private static decimal CalculatePrice(CoffeeChoice choice)
            {
                decimal price = 0;
                switch (choice)
                {
                    case CoffeeChoice.Plain:
                        price += 10.0m;
                        break;
            
                    case CoffeeChoice.WithMilk:
                        price += 5.0m;
                        goto case CoffeeChoice.Plain;
            
                    case CoffeeChoice.WithIceCream:
                        price += 7.0m;
                        goto case CoffeeChoice.Plain;
                }
                return price;
            }
            
    • Victoria@lemmy.blahaj.zone
      link
      fedilink
      English
      arrow-up
      35
      ·
      1 day ago

      from what i could find “because it was designed that way”

      For what it’s worth, C23 has updated labels to allow being placed before declarations.

    • sik0fewl@piefed.ca
      link
      fedilink
      English
      arrow-up
      15
      ·
      1 day ago

      Possibly because declarations were originally not statements in C? You could only declare variables at the start of a function, but not assign them to something at the same time.

      Not sure why it still wouldn’t be allowed, though, especially if an empty statement can be a statement.

      • balsoft@lemmy.ml
        link
        fedilink
        arrow-up
        9
        ·
        1 day ago

        I think it evolved like that:

        1. Declarations are separate entities to statements, because declarations do not translate to a machine code instruction
        2. Labels only make sense when attached to statements because they need to point to a particular machine code instruction <-- This should have been changed at least when declarations were allowed to be mixed with statements in compound statements
        3. Definitions are declarations plus an assignment, let’s make them a subset of a declaration <-- I think this is the biggest mistake of them all
        4. “Well, it’s already been that way for 40 years, too late to change it now!”
    • terranoid@lemmy.cafe
      link
      fedilink
      English
      arrow-up
      5
      ·
      1 day ago

      When it’s designed to be an expression

      while (int x = 1) { ... Modify x to eventually be zero... }
      

      That might make sense even if it looks weird. Kinda like a for loop.