Difference between '-std' and '--std' compiler flags - gcc

I've noticed that both -std and --std works for setting the standard for compiling. What is the difference between using a - and -- before std?
I've googled and found this, but it doesn't seem to mention anything about a single hyphen vs a double hyphen before a std.

-std=c99 is ok but -std c99 is an error. --std c99 is valid as is --std=c99. That's the only difference.
You can see that they map to the same action in opts-common.c:
struct option_map
{
/* Prefix of the option on the command line. */
const char *opt0;
/* If two argv elements are considered to be merged into one option,
prefix for the second element, otherwise NULL. */
const char *opt1;
/* The new prefix to map to. */
const char *new_prefix;
/* Whether at least one character is needed following opt1 or opt0
for this mapping to be used. (--optimize= is valid for -O, but
--warn- is not valid for -W.) */
bool another_char_needed;
/* Whether the original option is a negated form of the option
resulting from this map. */
bool negated;
};
static const struct option_map option_map[] =
{
...
{ "--std=", NULL, "-std=", false, false },
{ "--std", "", "-std=", false, false },
...
};

Related

mq_send: glibc forces param 2 to be nonnull

My static code analysis has found a bug in my code. I try to send an empty message:
mq_send(mqId, 0, 0, 1);
It says, the message buffer (parameter 2) should not be 0. It says this because the header says so:
glibc-2.29/rt/mqueue.h
/* Add message pointed by MSG_PTR to message queue MQDES. */
extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len,
unsigned int __msg_prio) __nonnull ((2));
glibc-2.29/sys/cdefs.h
/* The nonull function attribute allows to mark pointer parameters which
must not be NULL. */
#if __GNUC_PREREQ (3,3)
# define __nonnull(params) __attribute__ ((__nonnull__ params))
#else
# define __nonnull(params)
#endif
I know how to fix this. I just wonder: is this correctly implemented in glibc?
Neither linux man nor the posix standard says anything about passing a nullpointer. No error code or undefined behavior is described. In fact, when the length is 0, a null pointer is totally valid and works!

GCC, empty structs, and -Wunused-result

The following program causes gcc to emit -Wunused-result:
struct Empty { };
__attribute__((warn_unused_result))
static struct Empty func(void) {
return (struct Empty){};
}
int main(void) {
struct Empty res = func();
(void)res;
return 0;
}
Compiler output:
gcc -Wall -Wextra /tmp/test.c -c -o /tmp/test
/tmp/test.c: In function ‘main’:
/tmp/test.c:12:22: warning: ignoring return value of ‘func’, declared with attribute warn_unused_result [-Wunused-result]
struct Empty res = func();
^~~~~~
clang doesn't emit a warning.
Is this a bug or a feature?
(Empty struct as return value is useful in some code generation scenarios where a return value is always expected, but that is beside the question)
This does indeed appear to be a bug in GCC. I filed a bug report with them.
A workaround is to include a nameless bitfield in the "empty" structure:
struct Empty {char:1;};
extern void use_empty(struct Empty);
__attribute__((warn_unused_result))
extern struct Empty make_empty(void);
void should_warn(void)
{
make_empty();
}
void shouldnt_warn_1(void)
{
use_empty(make_empty());
}
void shouldnt_warn_2(void)
{
struct Empty e = make_empty();
use_empty(e);
}
warns only for 'should_warn'. This does mean that sizeof(struct Empty) is 1 rather than 0, and GCC generates an additional move instruction in both shouldnt_warn_1 and shouldnt_warn_2, but those are probably acceptable side-effects.
(Note that both a struct with no fields at all, and a struct with no named fields, are GNU extensions — in ISO C you must include at least one named field in every struct. Nameless bitfields, however, are standard, just obscure.)

module_param: display value in hex instead of decimal

Is it possible to display value of module_param when read, in hex?
I have this code in my linux device driver:
module_param(num_in_hex, ulong, 0644)
$cat /sys/module/my_module/parameters/num_in_hex
1234512345
Would like to see that value in hex, instead of decimal. Or, should I use different way like debugfs for this?
There is no ready parameter type (2nd argument of module_param macro), which output its argument as hexadecimal. But it is not difficult to implement it.
Module parameters are driven by callback functions, which extract parameter's value from string and write parameter's value to string.
// Set hexadecimal parameter
int param_set_hex(const char *val, const struct kernel_param *kp)
{
return kstrtoul(val, 16, (unsigned long*)kp->arg);
}
// Read hexadecimal parameter
int param_get_hex(char *buffer, const struct kernel_param *kp)
{
return scnprintf(buffer, PAGE_SIZE, "%lx", *((unsigned long*)kp->arg));
}
// Combine operations together
const struct kernel_param_ops param_ops_hex = {
.set = param_set_hex,
.get = param_get_hex
};
/*
* Macro for check type of variable, passed to `module_param`.
* Just reuse already existed macro for `ulong` type.
*/
#define param_check_hex(name, p) param_check_ulong(name, p)
// Everything is ready for use `module_param` with new type.
module_param(num_in_hex, hex, 0644);
Check include/linux/moduleparam.h for implementation module_param macro and kernel/params.c for implementation of operations for ready-made types (macro STANDARD_PARAM_DEF).

how to specify nftw flags

This is my nftw function, it works correctly before specifying flags FTW_DEPTH and FTW_PHYS:
if (nftw(argv[1], visit, 64, FTW_DEPTH | FTW_PHYS) != 0)
{
perror("nftw");
}
Also I have defined visit as:
int visit(const char *path, const struct stat *stat, int flags)
{
...
return 0;
}
BUT after compilation it gives error:
‘FTW_DEPTH’ undeclared (first use in this function)
Try using #define _XOPEN_SOURCE 500 before including ftw.h
if you look at ftw.h you see these lines :
#ifdef __USE_XOPEN_EXTENDED
/* Flags for fourth argument of `nftw'. */
enum
{
FTW_PHYS = 1, /* Perform physical walk, ignore symlinks. */
# define FTW_PHYS FTW_PHYS
FTW_MOUNT = 2, /* Report only files on same file system as the
argument. */
# define FTW_MOUNT FTW_MOUNT
FTW_CHDIR = 4, /* Change to current directory while processing it. */
# define FTW_CHDIR FTW_CHDIR
FTW_DEPTH = 8 /* Report files in directory before directory itself.*/
# define FTW_DEPTH FTW_DEPTH
# ifdef __USE_GNU
,
FTW_ACTIONRETVAL = 16 /* Assume callback to return FTW_* values instead of
zero to continue and non-zero to terminate. */
# define FTW_ACTIONRETVAL FTW_ACTIONRETVAL
# endif
};
so you can define this flag and error would be resolved:
#define __USE_XOPEN_EXTENDED

GCC: Customizing printf for string output

GCC allows customization of printf specifiers. However, I don't see how I can "teach" it to accept my string class for %s specifier. My string class is a simple wrapper over char pointer and has exactly one member variable (char * data) and no virtual functions. So, it's kind of ok to pass it as-is to printf-like functions in place of regular char *. The problem is that on gcc static analyzer prevents me from doing so and I have to explicitly cast it to const char * to avoid warnings or errors.
My cstring looks something like this:
class cstring
{
cstring() : data(NULL){}
cstring(const char * str) : data(strdup(str)){}
cstring(const cstring & str) : data(strdup(str.data)){}
~cstring()
{
free(data);
}
...
const char * c_str() const
{
return data;
}
private:
char * data;
};
Example code that uses cstring:
cstring str("my string");
printf("str: '%s'", str);
On GCC I get this error:
error: cannot pass objects of non-trivially-copyable type 'class cstring' through '...'
error: format '%s' expects argument of type 'char*', but argument 1 has type 'cstring' [-Werror=format]
cc1plus.exe: all warnings being treated as errors
The C++ standard doesn't require compilers to support this sort of code, and not all versions of gcc support it. (https://gcc.gnu.org/onlinedocs/gcc/Conditionally-supported-behavior.html suggests that gcc-6.0 does, at least - an open question whether it will work with classes such as the one here.)
The relevant section in the C++11 standard is 5.2.2 section 7:
When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_arg ...
Passing a potentially-evaluated argument of class type (Clause 9)
having a non-trivial copy constructor, a non-trivial move constructor,
or a non-trivial destructor, with no corresponding parameter, is
conditionally-supported with implementation-defined semantics.
(But look on the bright side: if you get into the habit of using c_str, then at least you won't get tripped up when/if you use std::string.)

Resources