lkml.org 
[lkml]   [2012]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH v2] Add kabs()
There is abs() and abs64().
They have following unwanted or suprising properties:
1) They return signed value
in math norms et al are unsigned

2) In finest Unix tradition they do not work reliably.
Quoting abs(3).
"Trying to take the absolute value of the most negative integer is not defined."

3) They expand type needlessly

4) There are 2 of them with different names
with gcc extensions __builtin_choose_expr(),
__builtin_types_compatible_p() we can mimic type dispatch as found
in modern programming languages.

Enter kabs().

kabs() has the following nice properties which should have been there
from day 1.

kabs() return unsigned value.
kabs() works for all integer types and return correct result.
sizeof(kabs(x)) == sizeof(x)

Mention kabs() in checkpatch.pl so people would gradually convert.
abs() and abs64() will eventually dissapear.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---

This one will actually compile.

include/linux/kernel.h | 29 +++++++++++++++++++++++++++++
scripts/checkpatch.pl | 6 ++++++
2 files changed, 35 insertions(+)

--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -188,6 +188,35 @@ extern int _cond_resched(void);
(__x < 0) ? -__x : __x; \
})

+#define kabs(x) \
+({ \
+ typeof(x) _x = (x); \
+ \
+ /* \
+ * "char", "signed char", "unsigned char" aren't compatible \
+ * regardless of -f{un,}signed-char. \
+ */ \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(_x), signed char), \
+ (unsigned char)({ _x < 0 ? -_x : _x; }), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(_x), char), \
+ (unsigned char)({ _x < 0 ? -_x : _x; }), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(_x), short), \
+ (unsigned short)({ _x < 0 ? -_x : _x; }), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(_x), int), \
+ (unsigned int)({ _x < 0 ? -_x : _x; }), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(_x), long), \
+ (unsigned long)({ _x < 0 ? -_x : _x; }), \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(_x), long long), \
+ (unsigned long long)({ _x < 0 ? -_x : _x; }), \
+ _x)))))); \
+})
+
#ifdef CONFIG_PROVE_LOCKING
void might_fault(void);
#else
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -3347,6 +3347,12 @@ sub process {
"__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
}

+# check for abs(), abs64()
+ if ($line =~ /\b(abs64|abs)\s*\(/) {
+ WARN("CONSIDER_KABS",
+ "$1 is obsolete, use kabs\n" . $herecurr);
+ }
+
# check for use of yield()
if ($line =~ /\byield\s*\(\s*\)/) {
WARN("YIELD",

\
 
 \ /
  Last update: 2012-04-23 15:25    [W:0.040 / U:0.020 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site