小编R..*_*R..的帖子

关于循环缓冲区中简洁索引处理的建议

我已经实现了一个循环缓冲区,我想要一个简洁的方法来更新缓冲区指针,同时正确处理环绕.

假设一个大小为10的数组,我的第一个响应是:

size_t ptr = 0;  
// do some work...
p = ++p % 10;
Run Code Online (Sandbox Code Playgroud)

静态分析,以及gcc -Wall -Wextra,由于序列点违规而正确地拍了我的手腕以查找未指定的行为.明显的修复方法如下:

p++;
p %= 10;
Run Code Online (Sandbox Code Playgroud)

然而,我正在寻找更简洁的东西(即一个单行)来"封装​​"这个操作.建议?除了p ++之外; p%= 10; :-)

c c99 sequence-points

2
推荐指数
1
解决办法
265
查看次数

在使用原子和futexes锁定代码时无法找到竞争条件

我正在尝试在我的Linux-futex和基于原子操作的锁定原语中调试导致竞争条件的死锁时非常糟糕.这是我正在使用的代码(与真实代码完全相同的逻辑,只是拉出了与问题无关的数据结构的依赖性):

int readers, writer, waiting;

void wrlock()
{
    int cur;
    while (atomic_swap(&writer, 1)) spin();
    while ((cur=readers)) futex_wait(&readers, cur);
}

void wrunlock()
{
    atomic_store(&writer, 0);
    if (waiting) futex_wake(&writer, ALL);
}

void rdlock()
{
    atomic_inc(&waiting);
    for (;;) {
        atomic_inc(&readers);
        if (!writer) return;
        atomic_dec(&readers);
        futex_wait(&writer, 1);
    }
}

void rdunlock()
{
    atomic_dec(&waiting);
    atomic_dec(&readers);
    if (writer) futex_wake(&readers, ALL);
}
Run Code Online (Sandbox Code Playgroud)

这些atomic_*spin功能非常明显.Linux futex ops是futex_wait(int *mem, int val)futex_wake(int *mem, int how_many_to_wake).

我运行到死锁状态是3个线程,readers==0,writer==1,waiting==2,和所有线程都在等待futex_wait …

c linux multithreading locking atomic

2
推荐指数
1
解决办法
416
查看次数

gcc对什么是左值感到困惑?

gcc在赋值错误中给出了无效的左值:

-2[(size_t *)new] = 0;
Run Code Online (Sandbox Code Playgroud)

将代码更改为以下内容使其消失:

((size_t *)new)[-2] = 0;
Run Code Online (Sandbox Code Playgroud)

但据我所知,两者在C中都是100%等效的.在非左值表达式中使用前者没有问题.这只是gcc中的一个错误吗?我用几个版本测试了它并得到了相同的结果.

c standards gcc lvalue

2
推荐指数
1
解决办法
286
查看次数

为什么setjmp传统上保存寄存器?

仅以i386为例,但是类似的问题适用于其他拱门。传统I386 jmp_buf通过保存setjmp由6个保存的寄存器:ebxesiediebpesp,和eip。其中,前4个是根据ABI保存的调用方,因此被调用的函数setjmp本身将使用自己保存的值覆盖它们(该值在的第一个和第二个返回之间可能会发生变化setjmp)。因此,将这些寄存器全部保存在其中有jmp_buf什么意义?仅保存堆栈和指令指针不是很好吗?

编辑:我错误地混淆了保存主叫方和保存被叫方,这是造成混乱的全部原因。很抱歉浪费大家的时间。

c x86 assembly longjmp

2
推荐指数
1
解决办法
943
查看次数

在嵌入式系统中使用 c 中的可变长度数组有问题吗?

有人告诉我用非常量值初始化数组是错误的,但我需要知道为什么。

int length = 5 ; 
int array[length];
Run Code Online (Sandbox Code Playgroud)

c memory arrays embedded

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

隐式类型转换

#include<stdio.h>
int main(void)
{ 
  signed int a=-1;
  unsigned int b=1;
  int c= a+b;
  printf("%d\n",c);

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

根据隐式类型转换的规则,如果一个操作数是unsigned int,则另一个将转换为unsigned int,并且结果将unsigned int处于二进制操作中.所以这里bunsigned int,a应类型强制转换为unsigned int.作为unsigned int类型总是+ VE,所以值a将是1.so c=1+1=2.但输出0.如何?

c

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

为什么,如果将char初始化为1然后左移7次并使用%d打印的值,它是否显示-128?

我知道签名值的2s补码表示.但二进制'10000000'如何成为-128十进制(使用%d).

for +64 binary rep ='01000000'for -64 binary rep ='11000000',这是'01000000'的2的补码

有人可以解释一下吗?

程序:

int main()
{
   char ch = 1;
   int count = 0;
   while(count != 8)
   {
     printf("Before shift val of ch = %d,count=%d\n",ch,count);
     ch = ch << 1;     

     printf("After  shift val of ch = %d,count=%d\n",ch,count);
     //printBinPattern(ch);  
     printf("*************************************\n");
     count++;
   }
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Before shift val of ch = 1, count=0
After  shift val of ch = 2, count=0
*************************************
...
... /* Output not shown */
Before shift …
Run Code Online (Sandbox Code Playgroud)

c c++

0
推荐指数
2
解决办法
345
查看次数

Linux IO优先级 - fifo命令?...要么?

假设两个进程(或线程)都调用write缓冲区已满的管道/套接字/终端,从而阻塞.当缓冲区空间可用时,是否可以保证谁首先写入?是FIFO订单吗?在全球范围内,还是在给定的优先级范围内,首先按优先级排序?还是完全随机/不确定?

饥饿的读书怎么样?首先调用read的数据会在数据可用时获取吗?

我在Linux上专门问一下,据我所知POSIX对这些问题没什么可说的,但是如果我错了,我也会感兴趣并且POSIX确实要求特定的行为.

c linux posix linux-kernel

0
推荐指数
1
解决办法
442
查看次数

将C字符串转换为unsigned char指针

我正在使用许多字节编译低级代码.在某些情况下,我可以使用双引号括起来的旧C字符串来定义.

但是当使用gcc或g ++进行编译时(不知道其他编译器的行为),它一直困扰着我的尖头字符串.

基本上我写这篇文章的时候

const unsigned char & refok = *"ABCDEFGHI";
Run Code Online (Sandbox Code Playgroud)

编辑:好吧,上面的代码并没有真正起作用,因为它理论上只保留对字符串的第一个字符的副本的引用.实际上,由于优化,它允许使用某些编译器访问所有字符串,但可能会随时中断.

或这个

const unsigned char oktoo[10] =
    {'A','B','C','D','E','F','G','H','I',0};
Run Code Online (Sandbox Code Playgroud)

编译器没有说什么.

但它绝对拒绝这一个:

const unsigned char * bad = "ABCDEFGHI";
Run Code Online (Sandbox Code Playgroud)

与消息

error: invalid conversion from 
   ‘const char*’ to ‘const unsigned char*’
   [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

这甚至不是警告,这是一个错误.

我想知道为什么这个问题应该比使用引用或将单个字符从有符号字符转换为无符号字符更重要?或者我错过了什么?

c++ casting

0
推荐指数
1
解决办法
4213
查看次数

为什么char [1]从我的输入文件中读取整个单词?

这就是我到目前为止所做的:我想从C++中读取文件中的单词,并且我只允许使用cstring库.这是我的一段代码

#include <cstring>
#include <fstream>
#include <stdio.h>

using namespace std;

int main(){

    ifstream file;
    char word[1];


    file.open("p.txt");



    while (!file.eof()){

        file >> word;
        cout << word << endl;

    }
    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,一次只读一个字.但我不明白这是如何工作的.任何大小的char数组怎么可能是char字[1]或char字[50]一次只读一个字而忽略空格.

而且我想将这些单词存储在动态数组中.我怎样才能做到这一点?任何指导将不胜感激?

c++ arrays file

0
推荐指数
1
解决办法
552
查看次数

Printf在下面的代码中抛出警告而不是错误

为什么编译器只为这个错误的程序产生警告而不是错误?

int main(){
    int a=3,b=4;
    printf("%d,%d");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c printf

-2
推荐指数
1
解决办法
65
查看次数

将弧度转换为像Google这样的度数

我试图将弧度转换为度数,但我没有得到与谷歌相同的结果

计算器和Pi我定义剂量输出所有数字.

如果您输入谷歌搜索:(1*180)/ 3.14159265然后你得到57.2957796,但我的程序是

输出:57.2958如果你输入谷歌搜索Pi你得到:3.14159265,但我的

剂量输出其余,输出:3.14159

我的代码是:

#include <iostream>
#define SHOW(X) cout << # X " = " << (X) << endl

using namespace std;

double Pi_test = 3.14159265;

float radian_to_degree(double  ENTER) {
  double Pi = 3.14159265;
  float degrees = (ENTER * 180) / Pi;
  return degrees;
}

int main (int argc, char * const argv[]) {
    SHOW( radian_to_degree(1) ); // 57.2958 not 57.2957795 like google, why?
    SHOW( Pi_test ); // …
Run Code Online (Sandbox Code Playgroud)

c++ math

-5
推荐指数
1
解决办法
4048
查看次数