Can this be done in FPC ? lazarus / 62-General ---------------------------------------------------------------------- 440bx · 2018-11-25 00:28 Hello, In C/C++ I can declare a pointer to point inside a null terminated character string as shown below: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const char* pchar = "some character string"; const char* otherpchar = pchar + 5;  // points to "character"  Can this be done in FPC ?  (important: the value of otherpchar must be determined at compile time not runtime.) Thank you for your help. ---------------------------------------------------------------------- creaothceann · 2018-11-25 01:18 Like this? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program StringPtrTest;uses        SysUtils;  const        Tab    = #9;        Text_s = 'Test';  var        s : array[1..Length(Text_s)] of AnsiChar = Text_s;        p : ^AnsiChar = @s[1];        i : PtrUInt absolute p;  beginWriteLn('$' + IntToHex(i, SizeOf(i) * 2) + Tab + p^);  Inc(i);WriteLn('$' + IntToHex(i, SizeOf(i) * 2) + Tab + p^);  Inc(i);WriteLn('$' + IntToHex(i, SizeOf(i) * 2) + Tab + p^);  Inc(i);WriteLn('$' + IntToHex(i, SizeOf(i) * 2) + Tab + p^);ReadLn;end. ---------------------------------------------------------------------- 440bx · 2018-11-25 01:51 Quote from: creaothceann on November 25, 2018, 02:18:08 amLike this? Yes!    that does what I want.  Thank you! ---------------------------------------------------------------------- lucamar · 2018-11-25 02:20 You don't even need variable i Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program project1;{$mode objfpc}{$H+} uses sysutils; const  Tab    = #9;  Text_s = 'Some character string'; var  s : array[1..Length(Text_s)] of AnsiChar = Text_s;  p : ^AnsiChar = @s[1];  {i : PtrUInt absolute p;}  x: Integer; begin  for x := 1 to Length(s) - 1 do begin    WriteLn('$' + IntToHex(PtrUInt(p), SizeOf(p) * 2) + Tab + p^);    Inc(p);  end;  WriteLn('$' + IntToHex(PtrUInt(p), SizeOf(p) * 2) + Tab + p^);  ReadLn;end. Drawback is that without it the typecast gives a "conversion not portable" hint but that is a non-issue in this case. ---------------------------------------------------------------------- howardpc · 2018-11-25 08:20 The program can be simplified to this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program StringPtrTest; const  Text_s = 'Test'; var  p, pEnd: PChar; begin  p := PChar(Text_s);  pEnd := p + Length(Text_s);  while p < pEnd do begin    WriteLn('$', PtrUInt(p), #9, p^);    Inc(p);  end;  ReadLn;end. ---------------------------------------------------------------------- Thaddy · 2018-11-25 10:14 Well close This is closer: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  s1:array[0..20] of char = 'some character string';  s2:array[0..15] of char absolute s1[5];   begin  writeln(s1);  writeln(s2);  end. Since C doesn't know strings: they are arrays of char. Basically anything that can be expressed in K&R C can be expressed in Pascal too. Also note the original code is unsafe (you can over-index it..) and this Pascal equivalent isn't.... Furthermore: that original code declares the equivalent of Pascal vars: not const, but const * Oh, and absolute means it is known at compile time. This will demonstrate that:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var   s1:array[0..20] of char = 'some character string';  s2:array[0..length(s1)-5] of char absolute s1[5];   begin  writeln(s1);  writeln(s2);  end. ---------------------------------------------------------------------- 440bx · 2018-11-25 10:54 Quote from: Thaddy on November 25, 2018, 11:14:57 amWell close This is closer: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  s1:array[0..20] of char = 'some character string';  s2:array[0..15] of char absolute s1[5];   begin  writeln(s1);  writeln(s2);  end. it's more succinct to simply write Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i s2 : pchar = @s1[5];and in addition to being more succinct, it also works in a const block whereas "absolute" does not. Claiming that C knows arrays is a bit of a stretch.  It knows pointers and pointer arithmetic.  Any pointer (as long as it isn't void) is an array. QuoteBasically anything that can be expressed in K&R C can be expressed in Pascal too.that might be true.  I don't remember K&R C well enough to argue that point BUT, FPC cannot express all that can be expressed in C++. QuoteAlso note the original code is unsafe (you can over-index it..) and this Pascal equivalent isn't.... That pascal equivalent is equivalently unsafe.  You can set the index in "absolute s1" to way past the boundaries of s1. That said, credit must be given to FPC for issuing a warning about it but, it won't stop you from doing it (which is a good thing.) QuoteFurthermore: that original code declares vars: not const, but const * there is no way to declare a const * in FPC.  i.e, FPC cannot make a difference between a pointer to an constant array of characters and a zero based array of char in memory.  In some situations (very few), C++ has stronger type checking than Pascal.  It is normally the opposite. ---------------------------------------------------------------------- Thaddy · 2018-11-25 11:19 The whole of the C language as envisioned by K&R is that everything is an array. C++ is a different story: Bjarne Soustrup wanted to re- invent object Pascal...with curly brackets... So everything is basically a comment... Note you can over complicate anything in any language... I simply showed that pointer dereferences are not needed. Lets save @ for emails... ---------------------------------------------------------------------- Thaddy · 2018-11-25 11:24 QuoteQuoteFurthermore: that original code declares vars: not const, but const * there is no way to declare a const * in FPC.  i.e, FPC cannot make a difference between a pointer to an constant array of characters and a zero based array of char in memory.  Do you really understand what I wrote? Pascal can do all of that. It is more a lack of knowledge from C programmers that always confuse some syntax with different meanings. Deliberately. What I wrote is true, it is not a meaning but a fact.... (the example code). Meanings can differ, facts don't. ---------------------------------------------------------------------- 440bx · 2018-11-25 12:59 Quote from: Thaddy on November 25, 2018, 12:24:21 pmWhat I wrote is true, it is not a meaning but a fact.... (the example code). Meanings can differ, facts don't. There is a very obvious fact in most of what you write and, that is, you're a legend in your own mind.  It's a start. ETA: You're making progress... you didn't get grumpy this time.  There might be hope for you.  (yes, I know, I'm an optimist.) ---------------------------------------------------------------------- Windsurfer · 2018-11-25 13:07 This is off topic, but I have not used pointers in fpc/lazarus LCL for many years. I know there are plenty of pointers in fpc and LCL, but how many places are there left where pointers are necessary for normal high level programming? This might merit a page in the wiki that C programmers could be directed to. ---------------------------------------------------------------------- Blaazen · 2018-11-25 13:43 @ Windsurfer Until you need some bindings to C library. This is from PortAudio:  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   PaStream = Pointer;  PPaStream = ^PaStream;  PPPaStream = ^PPaStream; ---------------------------------------------------------------------- marcov · 2018-11-25 13:49 Quote from: Windsurfer on November 25, 2018, 02:07:33 pmI know there are plenty of pointers in fpc and LCL, but how many places are there left where pointers are necessary for normal high level programming? True, but how often do you do purely high level programming? There is always  a bit of foreign language interfacing, decoding wire protocols (walking through a buffer), image manipulation, or something that just needs an extra bit of speed. Also inside the frameworks that you use, there is always some of this code, and you need to be able to read and fix it if possible. This is why I use a language that scales from low level to high level, instead of a purely ivory tower high level language. As for this thread, pointers are largely the same in principle, details can vary though (like pointers into literals, pointer type equivalence etc). ---------------------------------------------------------------------- 440bx · 2018-11-25 19:28 Quote from: Windsurfer on November 25, 2018, 02:07:33 pmI know there are plenty of pointers in fpc and LCL, but how many places are there left where pointers are necessary for normal high level programming? More than many "new" programmers realize.  Every class declaration is a pointer declaration.  Its instantiation is what sets the pointer value.  The fact that the compiler is "hiding" the pointer from the programmer by doing automatic dereferencing doesn't eliminate it. Object oriented programming is essentially a programming method that makes a level of pointer manipulation "accessible" to the "masses" through syntactic sugar. ---------------------------------------------------------------------- howardpc · 2018-11-25 19:34 Quote from: 440bx on November 25, 2018, 08:28:09 pmObject oriented programming is essentially a programming method that makes a level of pointer manipulation "accessible" to the "masses" through syntactic sugar. Ditto for several other declarations: strings (not shortstrings, of course), dynamic arrays, interfaces... ---------------------------------------------------------------------- 440bx · 2018-11-25 20:27 Quote from: howardpc on November 25, 2018, 08:34:23 pmDitto for several other declarations: strings (not shortstrings, of course), dynamic arrays, interfaces...   Indeed.  The list is long. ---------------------------------------------------------------------- Windsurfer · 2018-11-26 16:40 Thanks for the comments. I have to confess that I am a sugar addict. ---------------------------------------------------------------------- creaothceann · 2018-11-27 04:19 Pascal itself is syntactic sugar for machine code. ---------------------------------------------------------------------- 440bx · 2018-11-27 05:05 Quote from: creaothceann on November 27, 2018, 05:19:14 amPascal itself is syntactic sugar for machine code. Not really. It' s more accurate to think of Pascal and other high level languages as macro languages with richer descriptive abilities than plain machine code.    The additional information contained in the richer descriptions is useful to ensure code integrity (and often efficiency). Syntactic sugar changes the presentation but rarely adds anything useful, on the contrary, many times the syntactic sugar creates problems, which almost inevitably lead to poor solutions to the problems, thereby creating more problems.  it's a vicious circle. ---------------------------------------------------------------------- Thaddy · 2018-11-27 08:48 Quote from: 440bx on November 27, 2018, 06:05:45 amit's a vicious circle. It just demonstrates the lack of expression in the English language: circulus vitiosus does not mean the circle is a threat or in any way mean... Anyway, Latin is a (n almost)  dead language and assembler ( for any processor) is simply a notation. One could argue that it...... (oh, well) ---------------------------------------------------------------------- 440bx · 2018-11-27 09:09 Quote from: Thaddy on November 27, 2018, 09:48:49 amcirculus vitiosus does not mean the circle is a threat or in any way mean... That's quite a departure from the interpretation that has prevailed for centuries.  Good thing you're here to "modernize" it. ---------------------------------------------------------------------- SymbolicFrank · 2018-12-22 01:12 In C++, being fast is everything. You never copy a value, if you can pass a reference to it. Because copying takes time. Or, adding a count to an array (like, a string) is bad, because keeping it up to date costs a lot of overhead. That's also why there are many ways to do the same thing in C++, of which most are considered "harmful". It's up to the programmer to know which ones and when, and not to use them. Really, every time someone talks about the "do's and dont's" of programming, they're either discussing C++ or JavaScript. Because those two are a minefield. Almost all the things your really shouldn't do, are a non-issue in almost every other programming language. They won't allow it. In Pascal, correctness is everything. It goes through great lengths to prevent you shooting yourself in your foot. Everything should be logical and consistent. It should be obvious to the programmer what is going to happen. Just casting any data type to and from a generic pointer is not something you want to encourage. Most of the time, you don't want a reference to a variable, you want a copy. Simply to prevent many bugs. And if you really want a reference, specify it ("var"). In C++, there are three obvious ways to pass a parameter (copy, pointer, reference). Most of the time, it is not obvious which one to choose, and your program probably compiles anyway. While you have to use the exact same one as the function expects. Which is probably why the most common data type is "void *". Or: no defined type, the compiler will allow anything. In my experience, most Pascal bugs are caught by the compiler. Most C++ bugs happen at a different location than where the runtime exception happens. And it's far easier to create them. ---------------------------------------------------------------------- creaothceann · 2018-12-22 08:39 Quote from: SymbolicFrank on December 22, 2018, 02:12:57 amIn C++, being fast is everything. You never copy a value, if you can pass a reference to it. Because copying takes time.Except when copying is faster because it's done only once, while pointer dereferences add a small overhead. Or because pointers are larger than the data being copied, or because arrays of pointer values (used e.g. by jump tables) waste precious cache space. Though that's probably very rare. Quote from: SymbolicFrank on December 22, 2018, 02:12:57 amOr, adding a count to an array (like, a string) is bad, because keeping it up to date costs a lot of overhead.My impression was that many custom string solutions were created specifically to include a length field. ---------------------------------------------------------------------- fasdfasdfasdfasdfasdf · 2018-12-22 10:33 Quote from: SymbolicFrank on December 22, 2018, 02:12:57 amIn my experience, most Pascal bugs are caught by the compiler. Most C++ bugs happen at a different location than where the runtime exception happens. And it's far easier to create them. That's why you use things like ClangTidy etc. If you find a bug in pascal.. expect to wait a long time for someone to fix it. Same for Delphi. ---------------------------------------------------------------------- Thaddy · 2018-12-22 10:50 Quote from: r2r3 on December 22, 2018, 11:33:51 amThat's why you use things like ClangTidy etc. If you find a bug in pascal.. expect to wait a long time for someone to fix it. If it is a real bug and not a feature request it gets usually fixed very quick in FreePascal. QuoteSame for Delphi. That's another matter. They sell bug fixes as features.