Dani jojo Posted February 5, 2017 at 10:17 PM Report Share #602353 Posted February 5, 2017 at 10:17 PM Olá a todos, Existe algum motivo ou problema em declarar uma função estática num header? Já sabemos que uma função deste género tem internal linkage mas ao definirmos dentro do Source o compilador não se queixa. Se voltarmos a incluir o ficheiro num segundo Source file o compilador vai dar erro e dizer que a função não está definida. Aqui temos duas alternativas interpretamos o facto de ser estática como sendo única e exclusivamente para uso local ou ré-definimos a função no segundo source 🙂 Qual o problema de criar uma segunda definição nesse segundo source file. Ao fazer include é uma vez que a função é estática irá ser criada uma cópia. Aparentemente nada de mal poderá acontecer. Ou seja, se excluirmos questões de optimização existe realmente problema em definir a função estática dentro do header? Obrigado pelo suporte. Link to comment Share on other sites More sharing options...
TheSyvered Posted February 5, 2017 at 10:25 PM Report Share #602355 Posted February 5, 2017 at 10:25 PM Penso que, para além do problema de otimização que referiste, não há qualquer problema em o fazeres. Link to comment Share on other sites More sharing options...
Warrior Posted February 6, 2017 at 09:02 AM Report Share #602356 Posted February 6, 2017 at 09:02 AM Se a função é estática, não é suposto ser chamada de outro ficheiro. Se precisas de a chamar de outro ficheiro, então claramente não a devias ter declarado como estática dado que faz parte da interface daquele "ficheiro"/"programa"/"utilitário"/whatever o ficheiro representa. Reimplementar novamente noutro ficheiro é de longe a pior opção. Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted February 6, 2017 at 01:36 PM Report Share #602360 Posted February 6, 2017 at 01:36 PM eu gostava era de saber qual a razão da necessidade da declaração da função como estática ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Dani jojo Posted February 6, 2017 at 07:50 PM Author Report Share #602370 Posted February 6, 2017 at 07:50 PM 6 horas atrás, HappyHippyHippo disse: eu gostava era de saber qual a razão da necessidade da declaração da função como estática ... Não é importante para a questão uma vez que o compilador e a por conseguinte a própria linguagem nos permite fazer tal. Mas só para dar algum contexto eu por regra quando defino uma função como static faço-o dentro do source file uma vez que pretendo que essa função seja usada na translation unit na qual a defino. No entanto, já me aconteceu ver isso definido num header file. E isto fez-me pensar qual o impacto de se fazer tal coisa. Obrigado a todos pelo suporte e o tempo dispensado à minha questão. 1 Report Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted February 6, 2017 at 09:59 PM Report Share #602375 Posted February 6, 2017 at 09:59 PM 2 hours ago, Dani jojo said: Não é importante para a questão uma vez que o compilador e a por conseguinte a própria linguagem nos permite fazer tal. que não é importante, dizes tu. eu acho bem pertinente se a função é declarada como estática no header e terá o seu código duplicado nos vários object files, basta tirar o static para isso não acontecer (e fazer como toda a gente faz que é fazer a implementação no .c) queres um exemplo de algo que a linguagem premite e não deve ser feito ? olha para o C++, a multipla herança é como caminhar em casca de ovos : permite, mas o mais fácil é fazer algo que nunca deve ser feito ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Dani jojo Posted February 6, 2017 at 10:44 PM Author Report Share #602376 Posted February 6, 2017 at 10:44 PM 27 minutos atrás, HappyHippyHippo disse: que não é importante, dizes tu. eu acho bem pertinente Para a pergunta que eu fiz não é importante porque já todos percebemos a utilização. 28 minutos atrás, HappyHippyHippo disse: se a função é declarada como estática no header e terá o seu código duplicado nos vários object files, basta tirar o static para isso não acontecer (e fazer como toda a gente faz que é fazer a implementação no .c) Não é exactamente isso que acontece... A declaração é duplicada a definição não!!!! É static por isso tem Internal linkage. O que acontece é que terás que a definir novamente se a quiseres usar!!!!! Mas podes até ter duas funções com a mesma "assinatura" mas implementações diferentes certo? Mais se fizeres include noutro source file e tentares usar essa função sem a definires o compilador vai-te dizer que a função não está definida! Aquilo que tu queres dizer acontece se fizeres a definição no header que não é bem aquilo que eu perguntei. 32 minutos atrás, HappyHippyHippo disse: queres um exemplo de algo que a linguagem premite e não deve ser feito ? olha para o C++, a multipla herança é como caminhar em casca de ovos : permite, mas o mais fácil é fazer algo que nunca deve ser feito ... Não é o exemplo mais feliz para o caso... podias citar o uso do new... raw pointers... operador de indexação.... agora múltipla herança???? Só é problemático se o teu código é mal modelado, falta de arquitectura consistente, etc, etc! 1 Report Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted February 7, 2017 at 12:37 AM Report Share #602379 Posted February 7, 2017 at 12:37 AM 1 hour ago, Dani jojo said: Não é exactamente isso que acontece... A declaração é duplicada a definição não!!!! É static por isso tem Internal linkage. O que acontece é que terás que a definir novamente se a quiseres usar!!!!! Mas podes até ter duas funções com a mesma "assinatura" mas implementações diferentes certo? Mais se fizeres include noutro source file e tentares usar essa função sem a definires o compilador vai-te dizer que a função não está definida! Aquilo que tu queres dizer acontece se fizeres a definição no header que não é bem aquilo que eu perguntei. certo ... estás a dizer que este exemplo não acontece no teu computador: static.h #pragma once static int func(void) { return 10; } foo.h #pragma once int foo(void); bar.h #pragma once int bar(void); foo.c #include "static.h" #include "foo.h" #include <stdio.h> int foo(void) { return printf("foo : %d\n", func()); } bar.c #include "static.h" #include "bar.h" #include <stdio.h> int bar(void) { return printf("bar : %d\n", func()); } shell: $ objdump -t ./obj/src/bar.o ./obj/src/bar.o: file format pe-x86-64 SYMBOL TABLE: [ 0](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x0000000000000000 bar.c File [ 2](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 1) 0x0000000000000000 func <---------------------------------- AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0 [ 4](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x000000000000000b bar [ 5](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .text AUX scnlen 0x2c nreloc 2 nlnno 0 [ 7](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .data AUX scnlen 0x0 nreloc 0 nlnno 0 [ 9](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .bss AUX scnlen 0x0 nreloc 0 nlnno 0 [ 11](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .xdata AUX scnlen 0x14 nreloc 0 nlnno 0 [ 13](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .pdata AUX scnlen 0x18 nreloc 6 nlnno 0 [ 15](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .rdata AUX scnlen 0xa nreloc 0 nlnno 0 [ 17](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_info AUX scnlen 0x16f nreloc 5 nlnno 0 [ 19](sec 8)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_abbrev AUX scnlen 0x51 nreloc 0 nlnno 0 [ 21](sec 9)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_aranges AUX scnlen 0x30 nreloc 2 nlnno 0 [ 23](sec 10)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_line AUX scnlen 0x59 nreloc 1 nlnno 0 [ 25](sec 12)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .rdata$zzz AUX scnlen 0x11 nreloc 0 nlnno 0 [ 27](sec 13)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_frame AUX scnlen 0x68 nreloc 4 nlnno 0 [ 29](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000000000 printf $ objdump -t ./obj/src/foo.o ./obj/src/foo.o: file format pe-x86-64 SYMBOL TABLE: [ 0](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x0000000000000000 foo.c File [ 2](sec 1)(fl 0x00)(ty 20)(scl 3) (nx 1) 0x0000000000000000 func <------------------------------------------------------ AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0 [ 4](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x000000000000000b foo [ 5](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .text AUX scnlen 0x2c nreloc 2 nlnno 0 [ 7](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .data AUX scnlen 0x0 nreloc 0 nlnno 0 [ 9](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .bss AUX scnlen 0x0 nreloc 0 nlnno 0 [ 11](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .xdata AUX scnlen 0x14 nreloc 0 nlnno 0 [ 13](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .pdata AUX scnlen 0x18 nreloc 6 nlnno 0 [ 15](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .rdata AUX scnlen 0xa nreloc 0 nlnno 0 [ 17](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_info AUX scnlen 0x16f nreloc 5 nlnno 0 [ 19](sec 8)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_abbrev AUX scnlen 0x51 nreloc 0 nlnno 0 [ 21](sec 9)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_aranges AUX scnlen 0x30 nreloc 2 nlnno 0 [ 23](sec 10)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_line AUX scnlen 0x59 nreloc 1 nlnno 0 [ 25](sec 12)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .rdata$zzz AUX scnlen 0x11 nreloc 0 nlnno 0 [ 27](sec 13)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .debug_frame AUX scnlen 0x68 nreloc 4 nlnno 0 [ 29](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000000000 printf 1 hour ago, Dani jojo said: Não é o exemplo mais feliz para o caso... podias citar o uso do new... raw pointers... operador de indexação.... agora múltipla herança???? Só é problemático se o teu código é mal modelado, falta de arquitectura consistente, etc, etc! o exemplo é optimo : apresenta algo que a linguagem deixa fazer, deixando uma porta escancarada para problemas sérios. os teus exemplos ficam a saber a pouco quando a sua utilização é obrigatória para resolução de certos problemas. a multipla heranla foi demonstrado por outras linguagem que é dispensável. IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
Dani jojo Posted February 7, 2017 at 06:33 PM Author Report Share #602393 Posted February 7, 2017 at 06:33 PM @HappyHippyHippo certissimo! Só uma nuance... aquilo que eu queria dizer no primeiro pos é que não fazes a definição no ficheiro static.h mas sim num ficheiro, e vamos chama-lo assim por uma questão de simplicidade static.c! A questão original é baseada neste principio. Mais uma vez obrigado! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now