Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá,
no post anterior sobre esse warning, marcado como resolvido, eu concluí que tratava-se da plataforma e coloquei um Debian. Perfeito, rápido, firmão, sem conflitos internos. E continuei meus códigos que funcionaram perfeitamente...
Tive dificuldades, parei tudo, e fiz o seguinte código que, resolvido, me permitiria continuar o codigão que deixei de lado. Eis:
#include <iostream>
#include <cstdio>
using namespace std;
void funcao ( char string[] ) {
cin >> string;
cout << string; }
int main(){
funcao("lorem ipsum_ ");
return(0); }
Era pro código coutar "lorem ipsum_", mas quem coutou foi o g++ : deprecated conversion. Mas esse é só um warning desagradável, o pobrema é que não imprime a string inserida!
Tenho que pôr índice na string dentro da função?
/home/lucasribeiro/Produção/OFICINA/_DESKTOP/oficina.cpp: In function ‘int main()’:
/home/lucasribeiro/Produção/OFICINA/_DESKTOP/oficina.cpp:17:24: warning: deprecated conversion from string
constant to ‘char*’ [-Wwrite-strings]
funcao("lorem ipsum_ ");
^Que sacanagem! Num dava pro g++ sugerir código? Os financiadores do projeto são corinthianos, perderam pro palmeiras, ficaram revoltados e apertaram nas verbas?
Então, Ísis...
eu não sabia que a classe string estava na iostream, grato.
E eu uso cstdio pois ainda não decidi o algoritmo inteiro, não sei quando vou usar fopen() & cia.
Ísis, olha minha saída de console para cada um dos três modos respectivamente:
string s
lorem ipsum_
* Ponteiro
using namespaces std;
^
standby.cpp: In function ‘void funcao(char*)’:
standby.cpp:5:3: error: ‘cout’ was not declared in this scope
cout << s;
^
standby.cpp:5:3: note: suggested alternative:
In file included from standby.cpp:1:0:
/usr/include/c++/4.9/iostream:61:18: note: ‘std::cout’
extern ostream cout; /// Linked to standard output
^
standby.cpp: In function ‘int main()’:
standby.cpp:9:33: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
funcao("\n\tlorem ippsum_\n\n");
^
lorem ipsum_
vetor
standby.cpp:2:7: error: expected nested-name-specifier before ‘namespaces’
using namespaces std;
^ cout << s;
^ funcao("lorem ippsum_ ");
^Mostrei o console mais por você mesmo. Decidi pela a classe string.
Achei que o problema. na verdade, era que eu tinha mais de uma versão do g++ instalada;
"conversão depreciada" parece sintaxe que não vale mais pra versão atual. Mas
não adiantou, será que tem que reiniciar o ambiente ou o pc??
Ísis, você sempre me ajuda! Então, obrigado mesmo...
Em C++, a não ser que você esteja estudando alocação de memória ou precise otimizar o código em termos de espaço utilizado (e saiba o que está fazendo), é melhor usar a classe string p/ textos.
Mas se você quer mesmo se livrar do warning (e entrar naqueles detalhes "sórdidos" da linguagem):
1- Literais como "lorem ipsum" são tidos como const char * (http://en.cppreference.com/w/cpp/language/string_literal)
2- Como você passa um const char p/ uma função que recebe um char , a opção -Wwrite-strings (veja ali na mensagem do compilador) produz o warning.
Da página do manual do GCC:
>
-Wwrite-strings
When compiling C, give string constants the type "const char[length]" so that copying the address of one into a non-"const" "char *" pointer produces a warning. These warnings help you find at compile time code that can try to write into a string constant, but only if you have been very careful about using "const" in declarations and prototypes. Otherwise, it is just a nuisance. This is why we did not make -Wall request these warnings.
When compiling C++, warn about the deprecated conversion from string literals to "char *". This warning is enabled by default for C++ programs.
Detalhe:
"Attempting to modify a string literal results in undefined behavior"
Veja que mesmo com esse warning (const char -> char , sem a escrita) o programa funcionou p/ mim (sem a escrita no const char *)
Atenção p/ o que você escreveu: é namespace, sem o 's' no final (por isso que não encontra cout nem nada)
eu pus o "s"? kkk, vivo fazendo isso...
É queu to desenvolvendo no bloco de notas "pluma", do mate-desktop, só que ainda não tem intelisense e depuração. Mas, pessoalmente, não me dei bem com as ides... ah pô! quanto mais virtude, mais defeito!
o teu funcionou mesmo com o comportamento indefinido, né
tenho que estudar a referência do cpp, a começar por aí
Eu tô criando um sisteminha tipo agenda, pra faculdade, mas que tbm suporte relatório e diário. Começando em console. Mas por uma questão de tempo, estou apertando o algoritmo ao mesmo tempo da escrita; então decido parte por parte. Se eu não tivesse em aprendizado seria o dobro mais rápido...
Grato
>
o teu funcionou mesmo com o comportamento indefinido, né
Não. Deu falha de segmentação. O warning não é relativo ao comportamento indefinido. A escrita num const char * é o comportamento indefinido.
Então eu não interpretei corretamente, preciso analisar a referência no site.
"Attempting to modify a string literal results in undefined behavior"
Você pareceu se referir ao modo, de resolver o código que mostrei, em que você usa o ponteiro "char *", sem o "const"...
using namespaces std;
^
standby.cpp: In function ‘void funcao(char*)’:
standby.cpp:5:3: error: ‘cout’ was not declared in this scope
cout << s;
^
standby.cpp:5:3: note: suggested alternative:
In file included from standby.cpp:1:0:
/usr/include/c++/4.9/iostream:61:18: note: ‘std::cout’
extern ostream cout; /// Linked to standard output
^
standby.cpp: In function ‘int main()’:
standby.cpp:9:33: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
funcao("\n\tlorem ippsum_\n\n");
^
lorem ipsum_
Que, mesmo com notes, warnings e errors, ainda assim funcionou!
tá valendo
Não. O undefined behavior é p/ o teu cin >> string. Se estamos usando a mesma versão do GCC, você também vai ter uma falha de segmentação.
Ok. Entendi. Certamente... Uso G++ e GCC ambos "4.9". Organizei a compilação em shell script; se te servir: https://gist.github.com/anonymous/5a30ad09038598238593.
Cara, pra isso (normalmente) se utiliza um Makefile.
http://pt.wikibooks.org/wiki/Programar_em_C/Makefiles
http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
http://mrbook.org/blog/tutorials/make/
http://www.codeproject.com/Articles/31488/Makefiles-in-Linux-An-Overview
Recomendo que leia a documentação oficial do make e, por que não, do sistema de build GNU: http://www.gnu.org/manual/manual.html#Software
Se gostar da ideia de trabalhar com Makefile, tenho um padrão que mantenho no github.
https://github.com/GBeckerRS/makefilePadrao
Ao executar o make, compila os arquivos de objeto na pasta obj e o executavel na pasta bin.
Ok, GBecker e Ísis, makefile na pauta!
Cara, string é palavra reservada da linguagem (é uma classe em C++). Não use isso como nome de variável.
E por que você incluiu cstdio se não está usando nada dele?
Os três códigos a seguir funcionam perfeitamente p/ mim.
void funcao(string s) {
int main() {
void funcao(char * s) {
int main() {
void funcao(char s[]) {
int main() {
Colei teu código e na execução ele dá falha de segmentação por causa da leitura. Mas repare que na saída do GCC existe um outro problema ali: arquivo ou diretório não encontrado. Resolva isso primeiro.