[libgpiod] [PATCH] bindings: cxx: make operator bool() explicit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A non-explicit operator bool() is dangerous: It allows unwanted conversion
to integral types:

gpiod::chip c;
int i = c;

This is a trivial example, but more insidious effects are possible, e.g. with
std::set<gpiod::chip>, which would use the operator bool() to implement element
comparison, thus turning such set into a set that has at most 2 elements: An
invalid (false) element and just 1 valid element:

std::set<gpiod::chip> s;
s.emplace();
s.emplace("/dev/gpiochip0");
s.emplace("/dev/gpiochip1");
// s.size() is still 2 even if both chips were opened!

Making the operator explicit disables this.

See e.g.
https://en.cppreference.com/w/cpp/language/implicit_conversion#The_safe_bool_problem
for more info on this.
---
 bindings/cxx/gpiod.hpp | 6 +++---
 bindings/cxx/line.cpp  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/bindings/cxx/gpiod.hpp b/bindings/cxx/gpiod.hpp
index b92597f..cf4489b 100644
--- a/bindings/cxx/gpiod.hpp
+++ b/bindings/cxx/gpiod.hpp
@@ -167,7 +167,7 @@ public:
 	 * @brief Check if this object holds a reference to a GPIO chip.
 	 * @return True if this object references a GPIO chip, false otherwise.
 	 */
-	GPIOD_API operator bool(void) const noexcept;
+	GPIOD_API explicit operator bool(void) const noexcept;
 
 	/**
 	 * @brief Check if this object doesn't hold a reference to a GPIO chip.
@@ -422,7 +422,7 @@ public:
 	 * @brief Check if this object holds a reference to any GPIO line.
 	 * @return True if this object references a GPIO line, false otherwise.
 	 */
-	GPIOD_API operator bool(void) const noexcept;
+	GPIOD_API explicit operator bool(void) const noexcept;
 
 	/**
 	 * @brief Check if this object doesn't reference any GPIO line.
@@ -630,7 +630,7 @@ public:
 	 * @brief Check if this object holds any lines.
 	 * @return True if this line_bulk holds at least one line, false otherwise.
 	 */
-	GPIOD_API operator bool(void) const noexcept;
+	GPIOD_API explicit operator bool(void) const noexcept;
 
 	/**
 	 * @brief Check if this object doesn't hold any lines.
diff --git a/bindings/cxx/line.cpp b/bindings/cxx/line.cpp
index f8d0e62..470ed20 100644
--- a/bindings/cxx/line.cpp
+++ b/bindings/cxx/line.cpp
@@ -147,7 +147,7 @@ bool line::event_wait(const ::std::chrono::nanoseconds& timeout) const
 
 	line_bulk event_bulk = bulk.event_wait(timeout);
 
-	return ::std::move(event_bulk);
+	return !!event_bulk;
 }
 
 line_event line::event_read(void) const
-- 
2.20.1




[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux