小编sky*_*ing的帖子

为什么不是`printf`中定义的`float`的说明符?

它看起来像它可能是,有(至少在C99),可以适用于长度修改int:%hhd,%hd,%ld%lldsigned char,short,longlong long.甚至还有一个长度修饰符适用于double:%Lf均值long double.

问题是他们为什么省略float?按照模式,它可能是%hf.

c floating-point printf rationale c-standard-library

69
推荐指数
4
解决办法
3392
查看次数

这是有效的C++ 11吗?

我有以下代码在g ++下编译,但不是用clang编译.

如果以各种次要方式进行更改,Clang将编译代码,例如合并2个名称空间声明.

// The problem disappears without namespaces.
namespace Root {
    // The problem disappears if 'g' is in the global namespace, and we change
    // the friend declaration to '::g'

    // The problem disappears if 'g' has void return type.

    // The problem disappears if we get rid of the 'Value' template argument
    // and the 'value' parameter.
    template<typename Value, typename Defaulted = void>
    bool g(Value value);

    // The problem disappears if MyClass is not a template.
    template<typename …
Run Code Online (Sandbox Code Playgroud)

c++ clang language-lawyer c++11

24
推荐指数
1
解决办法
426
查看次数

为什么`gmtime`会占用指针?

根据文档,struct tm *gmtime(const time_t *timer);应该将time_t指向转换timer为分解时间.

现在有没有理由为什么他们决定让函数取指针time_t而不是time_t直接传递?

据我所知,它time_t是算术类型,因此应该可以直接传递(我也觉得它适合于a long).此外,似乎有任何特定的NULL指针处理(这可能有动机传递指针).

有什么我想念的吗?今天还有什么相关的东西?

c time posix

19
推荐指数
2
解决办法
873
查看次数

Java7规范中的语法是否真的相同?

JLS v7 第18章中的语法似乎与文档中其他地方的结构不同,但对我来说似乎存在差异.特别是在第15章中,规则是:

RelationalExpression:
  ShiftExpression
  RelationalExpression < ShiftExpression
  RelationalExpression > ShiftExpression
  RelationalExpression <= ShiftExpression
  RelationalExpression >= ShiftExpression
  RelationalExpression instanceof ReferenceType
Run Code Online (Sandbox Code Playgroud)

这使得foo instanceof Bar一个RelationalExpression(因此也就是一个EqualityExpresson)可以在EqualityExpression规则中用作LHS,该规则产生foo instanceof Bar == false一个EqualityExpression.

但是在查看第18章中的语法时,他们对它进行了简化:

Expression2:
  Expression3 [Expression2Rest]

Expression2Rest:
  { InfixOp Expression3 }
  instanceof Type
Run Code Online (Sandbox Code Playgroud)

这看起来很奇怪,这意味着我们可以将Expression3二进制运算符链接在一起,或者我们可以检查一个类型Expression3.具体现在foo instanceof Bar是一个Expression2,但我没有看到使用Expression2平等比较的LHS 是有效的.

我是否错过了第18章的语法中的某些内容foo instanceof Bar == false?请注意,根据第15章中的规则并根据我的编译器,它是一个有效的表达式.

java grammar language-lawyer java-7

13
推荐指数
1
解决办法
341
查看次数

什么是`scanf`应该与不完整的指数部分做什么?

rc = scanf("%f", &flt);输入为例42ex.scanf读取的实现会42e认为它会在之后遇到一个数字或符号,并在读取时首先意识到x它没有得到它.如果它在这一点上推回都xe?或者它应该只推回x.

我想问的原因是将GNU的libc中的后续调用gets返回ex表明他们已经推后两xe,但标准说:

除非规范包含n个指定符,否则从流中读取输入项.输入项目被定义为输入字符的最长序列,其不超过任何指定的字段宽度,并且是匹配输入序列的前缀或后缀[245]输入项目之后的第一个字符(如果有)仍然未读.如果输入项的长度为零,则指令的执行失败; 除非文件结束,编码错误或读取错误阻止了流的输入,否则此条件是匹配失败,在这种情况下,它是输入失败.

我将其解释为因为42e匹配输入序列的前缀(因为例如42e1将是匹配的输入序列),这应该意味着它将被42e视为应该被读取的输入项而仅留下x未读.如果流仅支持单个字符回退,那么实现起来也会更方便.

c glibc c99 language-lawyer

11
推荐指数
1
解决办法
104
查看次数

为什么stdio中的某些函数将流作为最后一个参数?

stdio中的一些函数似乎将流作为最后一个参数,例如:

char    *fgets(char *restrict, int, FILE *restrict);
int      fputs(const char *restrict, FILE *restrict);
size_t   fread(void *restrict, size_t, size_t, FILE *restrict);
size_t   fwrite(const void *restrict, size_t, size_t, FILE *restrict);
Run Code Online (Sandbox Code Playgroud)

有些人将它作为第一个论点:

int      fgetpos(FILE *restrict, fpos_t *restrict);
int      fseek(FILE *, long, int);
Run Code Online (Sandbox Code Playgroud)

为什么这种不一致?这些功能是在标准库演变的不同时间添加的吗?在那种情况下,这是第一次,为什么公约改变了?

我意识到,由于省略号(并且类似于首先和最后),fprintf与朋友一起或多或少地需要FILE*第一个(或至少早期fclose).

c libc

10
推荐指数
1
解决办法
212
查看次数

如何使用`offsetof`以标准符合方式访问字段?

假设我有一个结构并将偏移量提取给成员:

struct A {
    int x;
};

size_t xoff = offsetof(A, x);
Run Code Online (Sandbox Code Playgroud)

如果指针以struct A标准符合方式提取成员,我该怎么办?当然假设我们有struct A*正确的偏移量.一种尝试是做类似的事情:

int getint(struct A* base, size_t off) {
    return *(int*)((char*)base + off); 
}
Run Code Online (Sandbox Code Playgroud)

这可能会工作,但要注意的例子指针算术只有似乎标准中定义,如果指针是相同的阵列(或一个过去的结束)的指针,这不一定是这种情况.从技术上讲,构造似乎依赖于未定义的行为.

另一种方法是

int getint(struct A* base, size_t off) {
    return *(int*)((uintptr_t)base + off);
}
Run Code Online (Sandbox Code Playgroud)

这也可能会起作用,但请注意,intptr_t不需要存在,据我所知,算术intptr_t不需要产生正确的结果(例如我记得有些CPU有能力处理非字节对齐的地址,这会建议在数组中intptr_t每个步骤增加8 char.

看起来标准中有遗忘的东西(或者我错过的东西).

c pointers offsetof language-lawyer

10
推荐指数
1
解决办法
253
查看次数

在struct中使用__attribute __((aligned())),为什么sizeof的结果是这样的?

这是我的测试代码:

#include <cstdio>
struct A {
    int  a;
    int  b;
    int  c __attribute__((aligned(4096)));
    int  d;
}t;
int main()
{
    printf("%d\n",sizeof(t));

    return  0;
}
Run Code Online (Sandbox Code Playgroud)

结果是8192,但我无法弄清楚原因.

c memory-management

10
推荐指数
1
解决办法
447
查看次数

为什么gdb看不到'stdio`何时被更改?

根据GNU C库,它允许分配stdio就好像它们是普通变量(我知道这是一个扩展).我试过以下程序:

#include <stdio.h>
int main()
{
    stdout = NULL;

    printf("Crash and %s\n", "burn");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在运行程序时,它将按预期进行段错误,但是当我gdb以值运行时stdout仍然不是NULL:

_IO_vfprintf_internal (s=0x0, format=0x400631 "Crash and %s\n",    ap=0x7fffffffe210) at vfprintf.c:1297
1297    vfprintf.c: No such file or directory.
(gdb) print stdout
$1 = (struct _IO_FILE *) 0x7ffff7dd77a0
(gdb) 
Run Code Online (Sandbox Code Playgroud)

为什么不gdb报告正确的值stdout

进一步调查我发现它似乎存储stdout在地址0x600940,寻找struct _IO_FILE*那里我找到一个与gdb报告相同的指针stdio:

(gdb) print stdout
$1 = (struct _IO_FILE *) 0x7ffff7dd77a0
(gdb) print …
Run Code Online (Sandbox Code Playgroud)

c gdb gnu

6
推荐指数
1
解决办法
174
查看次数

-Wbad-function-cast的目的是什么,为什么它只适用于直接返回值?

还有的警告的理由在这里,但没有回答的全貌.例如,以下代码触发警告:

(int)round(M_PI);
Run Code Online (Sandbox Code Playgroud)

但另一方面,以下代码不会:

double d;
(int)(d = round(M_PI));
Run Code Online (Sandbox Code Playgroud)

这不是:

(int)M_PI;
Run Code Online (Sandbox Code Playgroud)

的理由是,你不应该转换简单地铸造为int,但你应该使用round,floor或类似的功能.但是,使用round仍然会触发警告,但如上所示,类型化常量或指定的变量则不会.

所以,如果它是坏的,从投doubleint,那么当你写为什么不报警触发(int)d(int)M_PI?如果你想转换返回值,应该以什么方式规避警告?是否有警告可以更正确/合理的方式处理这些危险的转换?

c gcc-warning

6
推荐指数
1
解决办法
2172
查看次数