我有一小段关于sizeof三元运算符的运算符的代码:
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a = true;
printf("%zu\n", sizeof(bool)); // Ok
printf("%zu\n", sizeof(a)); // Ok
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出(GCC):
1
1
4 // Why 4?
Run Code Online (Sandbox Code Playgroud)
但在这里,
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
Run Code Online (Sandbox Code Playgroud)
三元运算符返回boolean类型,sizeof bool类型是1C中的字节.
那为什么要sizeof(a ? true : false)输出四个字节?
我试过执行以下程序:
#include <stdio.h>
int main() {
signed char a = -5;
unsigned char b = -5;
int c = -5;
unsigned int d = -5;
if (a == b)
printf("\r\n char is SAME!!!");
else
printf("\r\n char is DIFF!!!");
if (c == d)
printf("\r\n int is SAME!!!");
else
printf("\r\n int is DIFF!!!");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于这个程序,我得到输出:
char是DIFF !!! int是相同的!
为什么我们两者都有不同的输出?
输出应该如下?
char是相同的!int是相同的!
一个键盘连接.
如果 along int和 aint在平台上的表示相同,它们是否严格相同?根据 C 标准,这些类型在平台上的行为是否有任何不同?
例如。这是否总是有效:
int int_var;
long long_var;
void long_bar(long *l);
void int_bar(int *i);
void foo()
{
long_bar(&int_var); /* Always OK? */
int_bar(&long_var);
}
Run Code Online (Sandbox Code Playgroud)
我想同样的问题适用于 short 和 int,如果它们碰巧是相同的表示。
在讨论如何为int32_t没有 stdint.h 的嵌入式 C89 编译器定义一个-like typedef时出现了问题,即 as intorlong以及是否重要。
这对我来说是一个真正的WTF,看起来像GCC中的一个错误,但我想让社区看一看并为我找到解决方案.
这是我能想到的最简单的程序:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint16_t i = 1;
uint16_t j = 2;
i += j;
return i;
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用-Werror=conversion标志在GCC上编译它,我正在使用我的大部分代码.
这是结果:
.code.tio.c: In function ‘main’:
.code.tio.c:9:7: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i += j;
Run Code Online (Sandbox Code Playgroud)
此代码会发生同样的错误:
uint16_t i = 1;
i += ((uint16_t)3);
Run Code Online (Sandbox Code Playgroud)
错误是
.code.tio.c: In function ‘main’:
.code.tio.c:7:7: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i …Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
#include <string.h>
int main(void)
{
char ch='a';
printf("sizeof(ch) = %d\n", sizeof(ch));
printf("sizeof('a') = %d\n", sizeof('a'));
printf("sizeof('a'+'b'+'C') = %d\n", sizeof('a'+'b'+'C'));
printf("sizeof(\"a\") = %d\n", sizeof("a"));
}
Run Code Online (Sandbox Code Playgroud)
该程序用于sizeof计算大小.为什么尺寸'a'不同于ch(哪里ch='a')?
sizeof(ch) = 1
sizeof('a') = 4
sizeof('a'+'b'+'C') = 4
sizeof("a") = 2
Run Code Online (Sandbox Code Playgroud) 在以下代码中:
short = ((byte2 << 8) | (byte1 & 0xFF))
Run Code Online (Sandbox Code Playgroud)
目的是&0xFF什么?因为其他有时我认为它写成:
short = ((byte2 << 8) | byte1)
Run Code Online (Sandbox Code Playgroud)
这似乎也很好吗?
我有一个简单的函数测试,如果两个数组彼此相反。它们似乎是相同的,只是tmp变量不同。一个有效,另一个无效。我一辈子都无法弄清楚为什么编译器会对此进行优化-如果确实存在优化问题(我的编译器是IAR Workbench v4.30.1)。这是我的代码:
// this works as expected
uint8 verifyInverseBuffer(uint8 *buf, uint8 *bufi, uint32 len)
{
uint8 tmp;
for (uint32 i = 0; i < len; i++)
{
tmp = ~bufi[i];
if (buf[i] != tmp)
{
return 0;
}
}
return 1;
}
// this does NOT work as expected (I only removed the tmp!)
uint8 verifyInverseBuffer(uint8 *buf, uint8 *bufi, uint32 len)
{
for (uint32 i = 0; i < len; i++)
{
if (buf[i] != (~bufi[i]))
{ …Run Code Online (Sandbox Code Playgroud) 考虑以下程序.
#include <stdio.h>
int negative(int A) {
return (A & 0x80000000) != 0;
}
int divide(int A, int B) {
printf("A = %d\n", A);
printf("negative(A) = %d\n", negative(A));
if (negative(A)) {
A = ~A + 1;
printf("A = %d\n", A);
printf("negative(A) = %d\n", negative(A));
}
if (A < B) return 0;
return 1;
}
int main(){
divide(-2147483648, -1);
}
Run Code Online (Sandbox Code Playgroud)
在没有编译器优化的情况下编译它时,它会产生预期的结果.
gcc -Wall -Werror -g -o TestNegative TestNegative.c
./TestNegative
A = -2147483648
negative(A) = 1
A = -2147483648
negative(A) = 1 …Run Code Online (Sandbox Code Playgroud) 考虑以下清单:
#include <type_traits>
#include <cstdint>
static_assert(std::is_same_v<decltype(31), int32_t>);
static_assert(std::is_same_v<decltype(31u), uint32_t>);
static_assert(std::is_same_v<decltype((signed char)1 << 1), int32_t>);
static_assert(std::is_same_v<decltype((signed char)1 << 1u), int32_t>);
static_assert(std::is_same_v<decltype((unsigned char)1 << 1), int32_t>);
// Signed result for unsigned char
static_assert(std::is_same_v<decltype((unsigned char)1 << 1u), int32_t>);
// But unsigned for uint32_t
static_assert(std::is_same_v<decltype(1u << 1u), uint32_t>);
Run Code Online (Sandbox Code Playgroud)
它可以与 GCC 和 Clang 很好地编译。我很困惑operator<<(uint8_t, uint32_t)。为什么要签署结果?
我在项目中切换到固定长度的整数类型主要是因为它们帮助我在使用它们时更清楚地考虑整数大小.包括他们通过#include <inttypes.h>还包括了如印刷宏一帮其他的宏PRIu32,PRIu64...
要为固定长度变量分配常量值,我可以使用像UINT32_C()和的宏INT32_C().每当我分配一个恒定值时,我就开始使用它们.
这导致代码类似于:
uint64_t i;
for (i = UINT64_C(0); i < UINT64_C(10); i++) { ... }
Run Code Online (Sandbox Code Playgroud)
现在我看到几个不关心它的例子.一个是stdbool.h包含文件:
#define bool _Bool
#define false 0
#define true 1
Run Code Online (Sandbox Code Playgroud)
bool在我的机器上有1个字节的大小,所以它看起来不像int.但是,0和1应应自动转为正确的类型由编译器整数.如果我在我的示例中使用它,代码将更容易阅读:
uint64_t i;
for (i = 0; i < 10; i++) { ... }
Run Code Online (Sandbox Code Playgroud)
那么我何时应该使用固定长度的常量宏UINT32_C(),何时应该将该工作留给编译器(我正在使用GCC)?如果我在MISRA C中编写代码怎么办?