Luk*_*uky 1 c c++ pointers arduino ragel
我注意到以下C代码给出了"警告:初始化从指针目标类型中丢弃限定符",但它仍然按预期编译和运行(输出'W'字符).
#include <stdio.h>
int main(int argc, char *argv[])
{
char buffer[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};
const char* p = &buffer[0];
char* c = (p + 6);
printf("%c\n",*c);
}
Run Code Online (Sandbox Code Playgroud)
在C++中,相当类似的代码根本不会编译抱怨"错误:从'const char*'到'char*'的无效转换"
#include <iostream>
using namespace std;
int main()
{
char buffer[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};
const char* p = &buffer[0];
char* c = p + 6;
cout << *c;
cout << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是什么原因?
是否有可能修复C++代码以使其编译(和行为)就像它的C对应物一样?
更好的解释:感谢您的所有答案,但大多数人没有得到我真正的问题所以我会尝试更详细地解释.
我正在使用用C编写的库.标题中的函数原型是这样的:
void parse (const char* p, uint16_t len, uint8_t is_eof);
Run Code Online (Sandbox Code Playgroud)
在这个函数的实现中,碰巧运行代码就好了
char* c = p + 6;
Run Code Online (Sandbox Code Playgroud)
如果我用C编写代码并针对这个库进行编译,一切都很好.
现在我想用C++移植这个库,因为我需要在C++项目中使用它.我通过将函数参数重新定义为变量而不是常量来成功移植库.但由于p指针实际上不需要改变,我宁愿将其定义为常量,就像在原始的C lib中一样.放置变量而不是常量我最终移植了一个库而没有保留所有原始语义.这很糟糕,因为我不知道C++库是否与原始C库一样运行.
我希望这很清楚.
(希望)更好的解释:
我正在按照AVR教程中的教程 - [CODE] [C]使用Ragel灵活/高效地解析字符串,问题与parse_microscript()功能有关.
由于我想Serial.println();在解析器中嵌入Arduino代码(即),我试图用C++宿主语言编译这个Ragel解析器,而不是像教程中提出的那样编译C语言.
首先,我尝试包含Arduino.h在生成的C代码中,但Arduino IDE将无法编译(我相信因为混合了C和C++代码).
然后我尝试从相同的Ragel脚本生成C++代码,但是当编译多个"从'const char*'到'char*'的无效转换"时,会触发错误,定位生成的代码.
使其在C++中工作的唯一方法是删除所有常量关键字.这很糟糕,因为我正在改变C代码的原始语义,但它有效.
我试图找出提供上述C和C++片段的问题,但我可能很难解释这一点.
接受的答案是让C++代码片段编译的内容,但是当我在Arduino代码中尝试这个解决方案时它不起作用.
我把使用命令编译的工作Ragel脚本ragel -G2 -o microscript.cpp microscript.rl:
#include "qp_port.h"
#include "pelican.h"
#include "bsp.h"
#include "Arduino.h"
static uint16_t currentNumber;
%%{
machine microscript;
action ClearNumber {
currentNumber = 0;
}
action PrintNumber {
Serial.print("parameter: ");
Serial.println(currentNumber);
}
action RecordDigit {
uint8_t digit = (*p) - '0';
currentNumber = (currentNumber * 10) + digit;
}
number = ((digit @RecordDigit)+) > ClearNumber % PrintNumber;
whitespace = space+;
numlist = number (',' number)*;
crlf = '\r\n';
OK = crlf 'OK' crlf;
main := |*
crlf => {Serial.println("crlf");};
OK => {Serial.println("OK detected");};
*|;
}%%
%% Write data;
static uint8_t cs; /* The current parser state */
static char* ts;
static char* te;
static char* act;
void init_microscript() {
%% write init;
}
void parse_microscript(char* p, uint16_t len, uint8_t is_eof) {
char* pe = p + len; /* pe points to 1 byte beyond the end of this block of data */
char* eof = is_eof ? pe : ((char*) 0); /* Indicates the end of all data, 0 if not in this block */
%% write exec;
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到过,我只好到的第一个参数变化parse_microscript函数从常量char* p到char*p,并const char* pe到char* pe.
这就是为什么您应该将 C 和 C++ 视为单独的语言。
你可以抛弃const:
char* c = (char*) p + 6;
Run Code Online (Sandbox Code Playgroud)
但这确实是一种不好的做法。
如果你想改变一个指针为什么把它声明为const?
如果你希望它是 a const,你为什么要抛弃常量?
问以上问题,自己决定。
| 归档时间: |
|
| 查看次数: |
3784 次 |
| 最近记录: |