Recent

Author Topic: [CLOSED] ForceDirectories anomaly  (Read 2363 times)

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
[CLOSED] ForceDirectories anomaly
« on: May 09, 2023, 12:55:46 pm »
rtl/objpas/sysutils/disk.inc has function ForceDirectories(Const Dir: PathStr): Boolean;
https://gitlab.com/freepascal.org/fpc/source/-/blob/main/rtl/objpas/sysutils/disk.inc
The function might return true, false or raise an exception. Raising an exception is counterintuitive.

The stable documentation writes
Quote
76.15.128
ForceDirectories
Synopsis: Create a chain of directories
Declaration: function ForceDirectories(const Dir: RawByteString) : Boolean
function ForceDirectories(const Dir: UnicodeString) : Boolean
Visibility: default
Description: ForceDirectories tries to create any missing directories in Dir till the whole path in Dir
exists. It returns True if Dir already existed or was created successfully. If it failed to create any
of the parts, False is returned.

The development documentation has been modified for this function but it avoids this anomaly.
This mix of exceptions and boolean results is prone to easily insert bugs in code.
« Last Edit: May 19, 2023, 04:49:07 pm by lagprogramming »

PascalDragon

  • Hero Member
  • *****
  • Posts: 6049
  • Compiler Developer
Re: ForceDirectories anomaly
« Reply #1 on: May 10, 2023, 10:45:46 pm »
This exception is only raised if the Dir parameter is empty which is essentially an invalid argument for the function, after all it makes no sense to ensure that no path exists. Delphi behaves the same here, so nothing will be changed there.

AlexTP

  • Hero Member
  • *****
  • Posts: 2577
    • UVviewsoft
Re: ForceDirectories anomaly
« Reply #2 on: May 11, 2023, 10:21:41 pm »
No report in the bugtracker is needed, per PascalDragon.

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
Re: ForceDirectories anomaly
« Reply #3 on: May 19, 2023, 04:48:52 pm »
This exception is only raised if the Dir parameter is empty which is essentially an invalid argument for the function, after all it makes no sense to ensure that no path exists. Delphi behaves the same here, so nothing will be changed there.
mkdir(''); doesn't raise an exception.
directoryexists('',true); returns false, it doesn't raise an exception.
I have doubts ordinary programmers enclose forcedirectories in try...except/finally blocks. It's counterintuitive.
Anyway, because Delphi has this behavior, I have doubts Fpc and Lazarus would change the existing code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6049
  • Compiler Developer
Re: ForceDirectories anomaly
« Reply #4 on: May 21, 2023, 01:18:40 pm »
This exception is only raised if the Dir parameter is empty which is essentially an invalid argument for the function, after all it makes no sense to ensure that no path exists. Delphi behaves the same here, so nothing will be changed there.
mkdir(''); doesn't raise an exception.

ForceDirectories is not an equivalent to MkDir as that requires the parent directories to already exist.

I have doubts ordinary programmers enclose forcedirectories in try...except/finally blocks. It's counterintuitive.

Programmers will also very likely not pass empty strings to ForceDirectories which is the only case where that function raises an exception.

Anyway, because Delphi has this behavior, I have doubts Fpc and Lazarus would change the existing code.

Correct. This will not change.

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
Re: ForceDirectories anomaly
« Reply #5 on: May 21, 2023, 05:18:19 pm »
This exception is only raised if the Dir parameter is empty which is essentially an invalid argument for the function, after all it makes no sense to ensure that no path exists. Delphi behaves the same here, so nothing will be changed there.
mkdir(''); doesn't raise an exception.

ForceDirectories is not an equivalent to MkDir as that requires the parent directories to already exist.

I have doubts ordinary programmers enclose forcedirectories in try...except/finally blocks. It's counterintuitive.

Programmers will also very likely not pass empty strings to ForceDirectories which is the only case where that function raises an exception.

Code: Pascal  [Select][+][-]
  1. SetCurrentDir('/tmp/');ForceDirectories('subdir');
The above line creates a subdirectory in an existing '/tmp/' directory, same as
Code: Pascal  [Select][+][-]
  1. chdir('/tmp/');mkdir('subdir');//or
  2. SetCurrentDir('/tmp/');CreateDir('subdir');
So, same as mkdir and CreateDir, ForceDirectories supports relative paths, too.
After a chdir/SetCurrentDir to an existing directory, CreateDir('') always returns true while ForceDirectories('') always raises an exception. Both CreateDir and ForceDirectories are in the same rtl/objpas/sysutils/disk.inc file. I would expect ForceDirectories('') to return the same boolean result as CreateDir(''), or both of them to raise the same SCannotCreateEmptyDir exception.

Bart

  • Hero Member
  • *****
  • Posts: 5575
    • Bart en Mariska's Webstek
Re: [CLOSED] ForceDirectories anomaly
« Reply #6 on: May 21, 2023, 10:13:10 pm »
As pointed out: this is for Delphi compatibility.
I agree: a function that return a boolean should not raise an exception to report a special kind of error, but thak the Greek for that.

Bart

PascalDragon

  • Hero Member
  • *****
  • Posts: 6049
  • Compiler Developer
Re: ForceDirectories anomaly
« Reply #7 on: May 22, 2023, 10:31:33 pm »
This exception is only raised if the Dir parameter is empty which is essentially an invalid argument for the function, after all it makes no sense to ensure that no path exists. Delphi behaves the same here, so nothing will be changed there.
mkdir(''); doesn't raise an exception.

ForceDirectories is not an equivalent to MkDir as that requires the parent directories to already exist.

I have doubts ordinary programmers enclose forcedirectories in try...except/finally blocks. It's counterintuitive.

Programmers will also very likely not pass empty strings to ForceDirectories which is the only case where that function raises an exception.

Code: Pascal  [Select][+][-]
  1. SetCurrentDir('/tmp/');ForceDirectories('subdir');
The above line creates a subdirectory in an existing '/tmp/' directory, same as
Code: Pascal  [Select][+][-]
  1. chdir('/tmp/');mkdir('subdir');//or
  2. SetCurrentDir('/tmp/');CreateDir('subdir');
So, same as mkdir and CreateDir, ForceDirectories supports relative paths, too.
After a chdir/SetCurrentDir to an existing directory, CreateDir('') always returns true while ForceDirectories('') always raises an exception. Both CreateDir and ForceDirectories are in the same rtl/objpas/sysutils/disk.inc file. I would expect ForceDirectories('') to return the same boolean result as CreateDir(''), or both of them to raise the same SCannotCreateEmptyDir exception.

And ForceDirectories('/some/path/to/some/subdir') will also create any missing directory from some to subdir which CreateDir will not do. They are different functions with different usecases and for ForceDirectories it was decided - by the Delphi developers - that an empty directory is an invalid parameter which is different from the function simply having failed.

 

TinyPortal © 2005-2018