我已经实现了一个循环缓冲区,我想要一个简洁的方法来更新缓冲区指针,同时正确处理环绕.
假设一个大小为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; :-)
我正在尝试在我的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 …
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中的一个错误吗?我用几个版本测试了它并得到了相同的结果.
仅以i386为例,但是类似的问题适用于其他拱门。传统I386 jmp_buf通过保存setjmp由6个保存的寄存器:ebx,esi,edi,ebp,esp,和eip。其中,前4个是根据ABI保存的调用方,因此被调用的函数setjmp本身将使用自己保存的值覆盖它们(该值在的第一个和第二个返回之间可能会发生变化setjmp)。因此,将这些寄存器全部保存在其中有jmp_buf什么意义?仅保存堆栈和指令指针不是很好吗?
编辑:我错误地混淆了保存主叫方和保存被叫方,这是造成混乱的全部原因。很抱歉浪费大家的时间。
有人告诉我用非常量值初始化数组是错误的,但我需要知道为什么。
int length = 5 ;
int array[length];
Run Code Online (Sandbox Code Playgroud) #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处于二进制操作中.所以这里b的unsigned int,a应类型强制转换为unsigned int.作为unsigned int类型总是+ VE,所以值a将是1.so c=1+1=2.但输出0.如何?
我知道签名值的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) 假设两个进程(或线程)都调用write缓冲区已满的管道/套接字/终端,从而阻塞.当缓冲区空间可用时,是否可以保证谁首先写入?是FIFO订单吗?在全球范围内,还是在给定的优先级范围内,首先按优先级排序?还是完全随机/不确定?
饥饿的读书怎么样?首先调用read的数据会在数据可用时获取吗?
我在Linux上专门问一下,据我所知POSIX对这些问题没什么可说的,但是如果我错了,我也会感兴趣并且POSIX确实要求特定的行为.
我正在使用许多字节编译低级代码.在某些情况下,我可以使用双引号括起来的旧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++中读取文件中的单词,并且我只允许使用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]一次只读一个字而忽略空格.
而且我想将这些单词存储在动态数组中.我怎样才能做到这一点?任何指导将不胜感激?
为什么编译器只为这个错误的程序产生警告而不是错误?
int main(){
int a=3,b=4;
printf("%d,%d");
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我试图将弧度转换为度数,但我没有得到与谷歌相同的结果
计算器和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)