kuriose Variablendeklaration


  • Mod

    Belli schrieb:

    Aber gpio_desc ist der Name einer Struktur, wie kann ich den von einem Zeiger subtrahieren?

    Es kann ja durchaus noch eine Variable gpio_desc im gleichen Scope geben.

    Im übrigen ist der Name der Struktur immer noch struct gpio_desc , nicht gpio_desc wie in C++. Aber selbst wenn, dann ginge das ja trotzdem:

    struct foo { };
    foo foo; // Absolut in Ordnung in C++
    

    Geht nicht mehr bei einem typedef.

    (Das heißt nicht, dass du nicht Recht hast und der Code einfach Unsinn ist. Ich gehe sogar davon aus. Wollte bloß darauf aufmerksam machen, dass es möglich ist.)



  • SeppJ schrieb:

    struct foo { };
    foo foo; // Absolut in Ordnung in C++
    

    Geht nicht mehr bei einem typedef.

    Hab ich nicht gewusst ...



  • SeppJ schrieb:

    (Das heißt nicht, dass du nicht Recht hast und der Code einfach Unsinn ist. Ich gehe sogar davon aus.

    Wieso das denn? Da spricht doch überhaupt nichts für, im Gegenteil.


  • Mod

    Bashar schrieb:

    Wieso das denn? Da spricht doch überhaupt nichts für, im Gegenteil.

    Weil ich die Namensgebung, wie Belli, doch etwas kurios finde, auch wenn sie technisch möglich ist. Ich würde daher einen Tippfehler erwarten.



  • der OP schrieb:

    stammt aus dem Exynos GPIO driver

    Man sieht aber auch ohne diese Information, dass das kein Wegwerfbeispiel mit Tippfehler sein kann.



  • ich muss gestehen dass die 2 Zeilen vll. auch ein klein wenig aus dem Zusammenhang gerissen wurden und ich mir nicht mal sicher bin ob es sich um reines C oder doch C++ handelt. Aber da ich im Moment eher am Kontext interssiert bin und dieser kleine Stolperstein mir gestern eine Stunde lang den Nerv geraubt hat dachte ich man fragt lieber einmal die Spezialisten als dumm zu sterben.

    static ssize_t gpio_value_show(struct device *dev,
    		struct device_attribute *attr, char *buf)
    {
    	const struct gpio_desc	*desc = dev_get_drvdata(dev);
    	unsigned		gpio = desc - gpio_desc;
    	ssize_t			status;
    
    	mutex_lock(&sysfs_lock);
    
    	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
    		status = -EIO;
    	} else {
    		int value;
    
    		value = !!gpio_get_value_cansleep(gpio); //<--- an der Stelle würde ich behaupten es ist C++
    // "!!" in der kombi kenn ich nur als "missbrauch" des operator! um ein objekt als negiertes "nicht" zu bool zu konvertieren 
    		if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
    			value = !value;
    
    		status = sprintf(buf, "%d\n", value);
    	}
    
    	mutex_unlock(&sysfs_lock);
    	return status;
    }
    

    DAs ist jetzt nur die Methode der Vollständigkeit halber, für mich ist das Thema soweit erledigt, aber ihr dürft gern ncoh angeregt diskutieren 🙂


  • Mod

    Ich bin mir ziemlich sicher, dass es C ist. Nichts deutet auf C++. Viele Stellen (z.B. den "scoped" Mutex) könnte man mit C++ so viel schöner machen, das muss einen Grund haben, warum das nicht benutzt wird.

    Das !!foo ist wohl eine trickreiche (und evtl. schnellere) Schreibweise für foo ? 1 : 0 . Außerdem eine weitere Stelle, die man in C++ viel schöner mittels bool hätte lösen können.



  • ich habs nicht geschrieben XD
    ich würde es wahrscheinlich viel umständlicher machen ... in C fehlt mir ein wenig die Praxis, ich hab sonst immer für Atmel µController mit C programmiert aber sonst mich eher auf .NET oder Java beschränkt ... Anwendungen schreiben sich mit nem guten Framework einfach schneller und aufm µC wirds spätestens bei Interrupts und inline assembler unschön also muss man es nicht elegant machen es muss nur schnell sein.


  • Mod

    Schnell und elegant schließt sich nicht aus. Das war sogar die Hauptmotivation bei der Erfindung von C++.

    Trotzdem ist das reines C und für reines C auch ganz ok. Ich hätte wahrscheinlich ein paar Sachen anders gemacht, aber vielleicht hatte der Autor gute Gründe, die mir nicht bekannt sind.



  • SeppJ schrieb:

    Das !!foo ist wohl eine trickreiche (und evtl. schnellere) Schreibweise für** foo ? 1 : 0 **

    kannst du das bitte nochmal kurz erläutern? foo ? 1 : 0



  • Länger ausgeschrieben:

    int value;
    if (foo)
        value = 1;
    else
        value = 0;
    

    Wobei mir ehrlich gesagt der Sinn in diesem Zusammenhang fehlt...


  • Mod

    Nathan schrieb:

    Wobei mir ehrlich gesagt der Sinn in diesem Zusammenhang fehlt...

    Es wird ja hinterher ausgegeben. Da interessiert wahrscheinlich nur ob value == 0 war oder nicht. Da möchte man sich nicht sein Log mit dem genauen Wert vollmüllen.



  • Ach so.
    Gewissermaßen ein static_cast<bool>?


  • Mod

    Nathan schrieb:

    Ach so.
    Gewissermaßen ein static_cast<bool>?

    Ja.



  • SeppJ schrieb:

    Ich bin mir ziemlich sicher, dass es C ist. Nichts deutet auf C++. [...] könnte man mit C++ so viel schöner machen

    Was soll das C-Bashing? Ich finde den Code sehr lesbar und übersichtlich.

    static ssize_t gpio_value_show(struct device *dev,
            struct device_attribute *attr, char *buf)
    {
        const struct gpio_desc  *desc = dev_get_drvdata(dev);
        unsigned        gpio = desc - gpio_desc;
        ssize_t         status;
    
        mutex_lock(&sysfs_lock);
    
        if (!test_bit(FLAG_EXPORT, &desc->flags)) {
            status = -EIO;
        } else {
            int value;
    
            value = !!gpio_get_value_cansleep(gpio);
    
            if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
                value = !value;
    
            status = sprintf(buf, "%d\n", value);
        }
    
        mutex_unlock(&sysfs_lock);
        return status;
    }
    

    versus

    namespace
    {
      class gpio_value_show
      {
      public:
        gpio_value_show(device const& dev,
                        device_attribute const& attr)
          : dev(dev),
            attr(attr)
        {
        }
    
      private:
        device const& dev;
        device_attribute const& attr;
      };
    
      template <typename CharT>
      std::basic_ostream<CharT>&
      operator<<(std::basic_ostream<CharT>& os,
                 gpio_value_show const& gpio_value_show_dummy)
      {
        gpio_drvdata const& desc = gpio_value_show_dummy.dev.get_drvdata();
    
        std::lock_guard<type_of_sysfs_lock> yet_another_random_name(sysfs_lock);
    
        if (!(desc.get_flags() & FLAG_EXPORT))
        {
          if (os.exceptions() & std::ios_base::failbit)
            throw invalid_io_exception("FLAG_EXPORT");
          else
            os.setstate(std::ios_base::failbit)
        }
        else
        {
          std::size_t gpio = desc - gpio_desc;
          bool value = static_cast<bool>(gpio_get_value_cansleep(gpio));
    
          if (desc.get_flags() & FLAG_ACTIVE_LOW)
          {
            value = !value;
          }
    
          // ?: needed because of the boolalpha flag
          os << (value ? CharT('1') : CharT('0')) << CharT('\n');
        }
    
        return os;
      }
    }
    

    Der C Code ist schnell und es ist klar, was er macht.

    Der C++ Code ist (wie jeder C++ Code) überladen mit vermeintlich "höherer Abstraktion". Jedenfalls muss man erst einmal suchen, was da genau passiert. Die Hälfte ist Boilerplate und meistens ist Boilerplate und Code gemischt. Ausserdem bin ich sicher, dass das Binary um ein Vielfaches grösser ist. Und in der Ausführung um ein Vielfaches langsamer.



  • @unbash
    Dein Vergleich ist unsinnig.
    Man könnte auch schönen C++ Code schreiben.



  • SeppJ schrieb:

    Das !!foo ist wohl eine trickreiche (und evtl. schnellere) Schreibweise für foo ? 1 : 0 . Außerdem eine weitere Stelle, die man in C++ viel schöner mittels bool hätte lösen können.

    Wenn du damit static_cast<bool> meinst, das geht zwar, wird aber von MSVC mit einer sinnfreien "Performance-Warning" quittiert.
    Bei !! dagegen kommt keine.

    Und schneller ist da auch nix, ausser schneller zu tippen 🤡



  • Seit wann schreibt man nicht mehr was man meint, in dem Fall foo != 0 ?



  • Seit dem man nicht mehr if (FunktionDieBoolZurueckgibt() != false) schreibt...



  • Kind, Badewasser.


Anmelden zum Antworten